home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / level.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-15  |  75.2 KB  |  3,285 lines

  1. #include "light.hpp"
  2. #include "level.hpp"
  3. #include "game.hpp"
  4. #include "intsect.hpp"
  5. #include "lisp.hpp"
  6. #include "dprint.hpp"
  7. #include "particle.hpp"
  8. #include "objects.hpp"
  9. #include "jrand.hpp"
  10. #include "macs.hpp"
  11. #include "clisp.hpp"
  12. #include "status.hpp"
  13. #include "dev.hpp"
  14. #include "demo.hpp"
  15. #include "pcxread.hpp"
  16. #include "profile.hpp"
  17. #include "sbar.hpp"
  18. #include "cop.hpp"
  19. #include "nfserver.hpp"
  20. #include "lisp_gc.hpp"
  21.  
  22. #ifndef __POWERPC__
  23. #include <sys/stat.h>
  24. #endif
  25.  
  26. #include <time.h>
  27.  
  28. level *current_level;
  29.  
  30. game_object *level::attacker(game_object *who)
  31.   long d=0x7fffffff;
  32.   game_object *c=NULL;
  33.   view *f=the_game->first_view;
  34.   for (;f;f=f->next)
  35.   {
  36.     if (f->focus)
  37.     {
  38.       long tmp_d=abs(f->focus->x-who->x)+abs(f->focus->y-who->y);
  39.       if (tmp_d<d)
  40.       {
  41.     d=tmp_d;
  42.     c=f->focus;
  43.       }
  44.     }
  45.   }
  46.   CONDITION(c,"no attacker found");
  47.   return c; 
  48.  
  49.  
  50.  
  51. int level::is_attacker(game_object *who)
  52.   return who->controller()!=NULL;
  53. }
  54.  
  55.  
  56. game_object *level::main_character()
  57. {
  58.   return the_game->first_view->focus;
  59. }
  60.  
  61. void level::load_fail()
  62. {
  63.   if (map_fg)    jfree(map_fg);   map_fg=NULL;
  64.   if (map_bg)    jfree(map_bg);   map_bg=NULL;
  65.   if (Name)      jfree(Name);     Name=NULL;
  66.  
  67.   first_active=NULL;
  68.   view *f=player_list;
  69.   for (;f;f=f->next)
  70.     if (f->focus)
  71.       current_level->remove_object(f->focus);
  72.  
  73.   while (first)
  74.   {
  75.     first_active=first;
  76.     first=first->next;
  77.     if (dev_cont)
  78.       dev_cont->notify_deleted_object(first_active);
  79.     delete first_active;
  80.   }
  81.  
  82.   while (area_list)
  83.   {
  84.     area_controller *l=area_list;
  85.     area_list=area_list->next;
  86.     delete l;
  87.   }
  88.  
  89.   last=NULL;
  90.   delete_panims();
  91.   delete_all_lights();
  92.  
  93. }
  94.  
  95. level::~level() 
  96.   load_fail();
  97.   if (attack_list) jfree(attack_list);
  98.   if (target_list) jfree(target_list);
  99.   if (block_list) jfree(block_list);
  100.   if (all_block_list) jfree(all_block_list);
  101.   if (first_name) jfree(first_name);
  102. }
  103.  
  104. void level::restart()
  105. {
  106.   view *f;
  107.   game_object *found=NULL,*o;
  108.   f=the_game->first_view;
  109.   for (o=first;f && o;o=o->next)
  110.   {
  111.     while (f && !f->focus) f=f->next;
  112.     if (f)
  113.     {
  114.       if (!strcmp(object_names[o->otype],"START"))
  115.       {
  116.     if (!found) found=o;
  117.     f->focus->x=o->x;
  118.     f->focus->y=o->y;          
  119.     f->focus->set_hp(get_ability(f->focus->otype,start_hp));
  120.     f->focus->set_state(stopped);
  121.     f=f->next;
  122.       }
  123.     }
  124.   }
  125.   while (f)
  126.   {
  127.     if (f->focus)
  128.     {
  129.       f->focus->x=found->x;
  130.       f->focus->y=found->y;          
  131.       f->focus->set_hp(get_ability(f->focus->otype,start_hp));
  132.       f->focus->set_state(stopped);      
  133.     }
  134.     f=f->next;
  135.   }
  136. }
  137.  
  138.  
  139. void level::next_focus()
  140. {
  141. /*  int i;
  142.   for (i=0;i<total_objs;i++)
  143.     if (obj[i]==the_game->first_view->focus)
  144.     {      
  145.       int tries=total_objs;
  146.       do
  147.       {
  148.     i++;
  149.     if (i==total_objs)
  150.       i=0;
  151.     the_game->first_view->focus=obj[i];
  152.       }  while ((!the_game->first_view->focus->is_playable() || 
  153.          the_game->first_view->focus->hp<=0) && tries--);
  154.       return ;
  155.     }            */  
  156. }
  157.  
  158. void level::unactivate_all()
  159. {
  160.   first_active=NULL;
  161.   game_object *o=first;
  162.   attack_total=0;  // reset the attack list
  163.   target_total=0;
  164.   block_total=0;
  165.   all_block_total=0;
  166.  
  167.   for (;o;o=o->next)
  168.     o->active=0;
  169. }
  170.  
  171.  
  172. void level::pull_actives(game_object *o, game_object *&last_active, int &t)
  173. {
  174.   int i=o->total_objects();
  175.   for (;i;i--)        // pull any linked object into active list
  176.   {
  177.     game_object *other=o->get_object(i-1);
  178.     if (!other->active)
  179.     {
  180.       other->active=1;
  181.       if (other->can_block())              // if object can block other player, keep a list for fast testing
  182.       {
  183.     add_block(other);
  184.     add_all_block(other);
  185.       } else if (other->hurtable())
  186.         add_all_block(other);
  187.  
  188.       t++;
  189.       last_active->next_active=other;
  190.       last_active=other;    
  191.       pull_actives(o,last_active,t);
  192.     }
  193.   }
  194. }
  195.  
  196. int level::add_actives(long x1, long y1, long x2, long y2)
  197. {
  198.   int t=0;
  199.   game_object *last_active=NULL;
  200.   if (first_active)
  201.     for (last_active=first_active;last_active->next_active;last_active=last_active->next_active);
  202.  
  203.   game_object *o=first;
  204.   for (;o;o=o->next)
  205.   {    
  206.     if (!o->active)
  207.     {
  208.       long xr=figures[o->otype]->rangex,
  209.            yr=figures[o->otype]->rangey;
  210.  
  211.       if (o->x+xr>=x1 && o->x-xr<=x2 && o->y+yr>=y1 && o->y-yr<=y2)
  212.       {
  213.     
  214.     if (o->can_block())              // if object can block other player, keep a list for fast testing
  215.     {
  216.       add_block(o);
  217.       add_all_block(o);
  218.     } else if (o->hurtable())
  219.           add_all_block(o);
  220.       
  221.  
  222.     o->active=1;
  223.     t++;
  224.     if (!first_active)      
  225.       first_active=o;    
  226.     else
  227.           last_active->next_active=o;
  228.     last_active=o;
  229.  
  230.     pull_actives(o,last_active,t);    
  231.       }  
  232.     }  
  233.   }
  234.   if (last_active)
  235.     last_active->next_active=NULL;
  236.   return t;
  237. }
  238.  
  239.  
  240. int level::add_drawables(long x1, long y1, long x2, long y2)
  241. {
  242.   int t=0,ft=0;
  243.   game_object *last_active=NULL;
  244.   if (first_active)
  245.   {
  246.     for (last_active=first_active;last_active->next_active;last_active=last_active->next_active);
  247.   } else ft=1;
  248.  
  249.   game_object *o=first;
  250.   for (;o;o=o->next)
  251.   {    
  252.     if (ft || !o->active)
  253.     {
  254.       long xr=figures[o->otype]->draw_rangex,
  255.       yr=figures[o->otype]->draw_rangey;
  256.  
  257.       if (o->x+xr>=x1 && o->x-xr<=x2 && o->y+yr>=y1 && o->y-yr<=y2)
  258.       {
  259.     t++;
  260.     if (!first_active)      
  261.     first_active=o;    
  262.     else
  263.     last_active->next_active=o;
  264.     last_active=o;
  265.     o->active=1;
  266.       } else if (ft) o->active=0;  // if this is the first pass, then mark objects not in this ranges as not active
  267.     }
  268.   }
  269.   if (last_active)
  270.     last_active->next_active=NULL;
  271.   return t;
  272. }
  273.  
  274.  
  275. view *level::make_view_list(int nplayers)
  276. {
  277.   int startable;
  278.   CONDITION(nplayers>0,"make_view_list with <=0 players!\n");
  279.   view *f=NULL;
  280.   int j,use_type=current_start_type;
  281.   figures[use_type]->cache_in();
  282.   game_object *o,*last_start=NULL;
  283.   int num=0;
  284.   
  285.   for (j=0,o=first;o && j<nplayers;o=o->next)
  286.   {
  287.     if (!strcmp(object_names[o->otype],"START"))
  288.     {
  289.       f=new view(create(use_type,o->x,o->y),f,num); num++;
  290.       f->focus->set_controller(f);
  291.       add_object_after(f->focus,o);
  292.       j++;
  293.       last_start=o;
  294.     }
  295.   }
  296.  
  297.   // if we couldn't find enough starts then create the rest of the players at the original start
  298.   startable=j;  // if we haven't created anyone yet, it's because we can't
  299.  
  300.   for (;j<nplayers;j++)
  301.   {
  302.     if (startable)
  303.     {
  304.       game_object *o=create(use_type,f->focus->x,f->focus->y);
  305.       f=new view(o,f,num); num++;
  306.       f->focus->set_controller(f);
  307.       add_object_after(o,last_start);
  308.     }
  309.     else 
  310.     {
  311.       f=new view(NULL,f,num); 
  312.       num++;
  313.     }
  314.   }
  315.   return f;
  316. }
  317.  
  318. void level::wall_push()
  319. {
  320.   long sx1,sy1,sx2,sy2,xv,yv;
  321.   game_object *o=first_active;
  322.   for (;o;o=o->next_active)
  323.   {
  324.     if (o->pushable())
  325.     {
  326.       o->picture_space(sx1,sy1,sx2,sy2);
  327.       xv=sx1-o->x;
  328.       yv=0;
  329.       o->try_move(o->x,o->y-1,xv,yv,1);         // check for wall pushes on the left using feet
  330.       if (xv!=sx1-o->x)                         // is the character in the wall?
  331.       {
  332.     xv=-xv;
  333.     o->try_move(o->x,o->y-1,xv,yv,1);       // see how far to the right we can push the character
  334.     o->x+=xv;
  335.       } else
  336.       {
  337.     xv=sx2-o->x;
  338.     o->try_move(o->x,o->y-1,xv,yv,1);      // now check the right of the character for a wall
  339.     if (xv!=sx2-o->x)
  340.     {
  341.       xv=-xv;
  342.       o->try_move(o->x,o->y-1,xv,yv,1);
  343.       o->x+=xv;
  344.     }
  345.       }           
  346.     }
  347.   }
  348. }
  349.  
  350.  
  351. void level::try_pushback(game_object *subject,game_object *target)
  352. {
  353.   if (subject->pushable() && target->pushable() && 
  354.       subject->state!=dead && target->state!=dead &&
  355.       subject->state!=dieing && target->state!=dieing)
  356.   {
  357.     int b1=subject->push_range(),b2=target->push_range();
  358.     if (abs(subject->x-target->x)<b1+b2)
  359.     {
  360.       long tmove=b1+b2-abs(subject->x-target->x),xv,yv=0,xv2;
  361.       if (subject->x>target->x)
  362.         xv=tmove/2;
  363.       else xv=-tmove/2;
  364.       xv2=-xv;
  365.  
  366.       subject->try_move(subject->x,subject->y,xv,yv,3);
  367.       subject->x+=xv;
  368.  
  369.       yv=0;
  370.       target->try_move(target->x,target->y,xv2,yv,3);
  371.       target->x+=xv2;     
  372.     }
  373.   }
  374. }
  375.  
  376. /*
  377. void level::check_collisions()
  378. {
  379.   game_object *target,*reciever=NULL;
  380.   long sx1,sy1,sx2,sy2,tx1,ty1,tx2,ty2,hitx,hity,
  381.       s_centerx,t_centerx;
  382.  
  383.   for (game_object *subject=first_active;subject;subject=subject->next_active)
  384.   {
  385.     subject->picture_space(sx1,sy1,sx2,sy2);   
  386.     s_centerx=subject->x_center();
  387.  
  388.     int hit=0;
  389.     reciever=NULL;
  390.     for (target=first_active;target;target=target->next_active)
  391.     {
  392.       if (target!=subject)
  393.       {
  394.     target->picture_space(tx1,ty1,tx2,ty2);
  395.  
  396.         if (!(sx2<tx1 || sx1>tx2 || sy1>ty2 || sy2<ty1))  // are they semi/overlapping?
  397.         {    
  398.       try_pushback(subject,target);
  399.       if (subject->can_hurt(target))    // see if we can hurt him before calculating
  400.       {        
  401.         t_centerx=target->x_center();
  402.         point_list *s_hit,*t_damage;
  403.                     
  404.         s_hit=subject->current_figure()->hit;      
  405.         t_damage=target->current_figure()->damage;
  406.  
  407.         unsigned char *s_dat=s_hit->data,
  408.         *t_dat;
  409.         int i,j;
  410.         for (i=(int)s_hit->tot-1;i>0 && !hit;i--)
  411.         {
  412.           for (t_dat=t_damage->data,j=(int)t_damage->tot-1;j>0 && !hit;j--)
  413.           {
  414.         long x1,y1,x2,y2,          // define the two line segments to check
  415.         xp1,yp1,xp2,yp2;
  416.  
  417.         xp1=target->x+target->tx(*t_dat);  t_dat++;          
  418.         yp1=target->y+target->ty(*t_dat);  t_dat++;
  419.         xp2=target->x+target->tx(*t_dat); 
  420.         yp2=target->y+target->ty(t_dat[1]); 
  421.  
  422.         x1=subject->x+subject->tx(s_dat[0]);  
  423.         y1=subject->y+subject->ty(s_dat[1]); 
  424.         x2=subject->x+subject->tx(s_dat[2]); 
  425.         y2=subject->y+subject->ty(s_dat[3]); 
  426.           
  427.  
  428.         // ok, now we know which line segemnts to check for intersection
  429.         // now check to see if (x1,y1-x2,y2) intercest with (xp1,yp1-xp2,yp2)
  430.         int _x2=x2,_y2=y2;          
  431.         setback_intersect(x1, y1, x2, y2, xp1, yp1, xp2, yp2,0);
  432.  
  433.  
  434.         if (x2!=_x2 || _y2!=y2)
  435.         {
  436.           reciever=target;
  437.           hitx=((x1+x2)/2+(xp1+xp2)/2)/2;
  438.           hity=((y1+y1)/2+(yp1+yp2)/2)/2;
  439.         }
  440.           } 
  441.           s_dat+=2;
  442.         }        
  443.       }
  444.     }
  445.       }  
  446.     }    
  447.     if (reciever)
  448.     {
  449.       reciever->do_damage((int)subject->current_figure()->hit_damage,subject,hitx,hity,0,0);
  450.       subject->note_attack(reciever);
  451.       hit=1;
  452.     }
  453.   }
  454. }
  455. */
  456.  
  457. game_object *level::boundary_setback(game_object *subject, long x1, long y1, long &x2, long &y2)
  458. {
  459.   game_object *l=NULL;
  460.   long tx1,ty1,tx2,ty2,t_centerx;
  461.   game_object *target=first_active;
  462.   game_object **blist=block_list;
  463.   int t=block_total;
  464.   for (;t;t--,blist++)
  465.   { 
  466.     target=*blist;
  467.     if (target!=subject && (target->total_objects()==0 || target->get_object(0)!=subject))
  468.     {
  469.       target->picture_space(tx1,ty1,tx2,ty2);
  470.       if (!((x2<tx1 && x1<tx1) || (x1>tx2 && x2>tx2) ||
  471.         (y1>ty2 && y2>ty2) || (y1<ty1 && y2<ty1)))  // are they semi/overlapping?
  472.       {         
  473.     t_centerx=target->x_center();
  474.     boundary *t_damage;
  475.     if (target->direction>0)
  476.     t_damage=target->current_figure()->f_damage;
  477.     else
  478.     t_damage=target->current_figure()->b_damage;
  479.     unsigned char *t_dat=t_damage->data,*ins=t_damage->inside;
  480.     int iter=t_damage->tot-1;
  481.     while(iter-->0)
  482.     {
  483.       long xp1=target->x+target->tx(*t_dat);  t_dat++;          
  484.       long yp1=target->y+target->ty(*t_dat);  t_dat++;
  485.       long xp2=target->x+target->tx(*t_dat); 
  486.       long yp2=target->y+target->ty(t_dat[1]); 
  487.  
  488.       // now check to see if (x1,y1-x2,y2) intercest with (xp1,yp1-xp2,yp2)
  489.       if (*ins)
  490.       {                
  491.         if (setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,1))
  492.         l=target;
  493.       }        
  494.       else
  495.       {
  496.         if (setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,-1))
  497.         l=target;
  498.       }        
  499.       ins++;
  500.       
  501.     }      
  502.       }      
  503.     }   
  504.   }
  505.   return l;       // return the last person we intersected  
  506. }
  507.  
  508.  
  509. game_object *level::all_boundary_setback(game_object *subject, long x1, long y1, long &x2, long &y2)
  510. {
  511.   game_object *l=NULL;
  512.   long tx1,ty1,tx2,ty2,t_centerx;
  513.   game_object *target=first_active;
  514.   game_object **blist=all_block_list;
  515.   int t=all_block_total;
  516.   for (;t;t--,blist++)
  517.   { 
  518.     target=*blist;
  519.     if (target!=subject && (target->total_objects()==0 || target->get_object(0)!=subject))
  520.     {
  521.       target->picture_space(tx1,ty1,tx2,ty2);
  522.       if (!((x2<tx1 && x1<tx1) || (x1>tx2 && x2>tx2) ||
  523.         (y1>ty2 && y2>ty2) || (y1<ty1 && y2<ty1)))  // are they semi/overlapping?
  524.       {         
  525.     t_centerx=target->x_center();
  526.     boundary *t_damage;
  527.     if (target->direction>0)
  528.     t_damage=target->current_figure()->f_damage;
  529.     else
  530.     t_damage=target->current_figure()->b_damage;
  531.     unsigned char *t_dat=t_damage->data,*ins=t_damage->inside;
  532.     int iter=t_damage->tot-1;
  533.     while(iter-->0)
  534.     {
  535.       long xp1=target->x+target->tx(*t_dat);  t_dat++;          
  536.       long yp1=target->y+target->ty(*t_dat);  t_dat++;
  537.       long xp2=target->x+target->tx(*t_dat); 
  538.       long yp2=target->y+target->ty(t_dat[1]); 
  539.  
  540.       // now check to see if (x1,y1-x2,y2) intercest with (xp1,yp1-xp2,yp2)
  541.       if (*ins)
  542.       {                
  543.         if (setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,1))
  544.         l=target;
  545.       }        
  546.       else
  547.       {
  548.         if (setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,-1))
  549.         l=target;
  550.       }        
  551.       ins++;      
  552.     }      
  553.       }      
  554.     }   
  555.   }
  556.   return l;       // return the last person we intersected  
  557. }
  558.  
  559.  
  560. //bFILE *rcheck=NULL,*rcheck_lp=NULL;
  561.  
  562. void level::interpolate_draw_objects(view *v)
  563. {
  564.   long old_x,old_y;
  565.   current_view=v;
  566.   
  567.   game_object *o=first_active;
  568.   for (;o;o=o->next_active)
  569.   {
  570.     old_x=o->x;
  571.     old_y=o->y;
  572.     o->x=(o->last_x+o->x)/2;
  573.     o->y=(o->last_y+o->y)/2;
  574.     o->last_x=old_x;
  575.     o->last_y=old_y;
  576.   }
  577.  
  578.   for (o=first_active;o;o=o->next_active)
  579.     o->draw();
  580.  
  581.   for (o=first_active;o;o=o->next_active)
  582.   {
  583.     o->x=o->last_x;
  584.     o->y=o->last_y;
  585.   }
  586. }
  587.  
  588. bFILE *rcheck=NULL,*rcheck_lp=NULL;
  589.  
  590. extern int sshot_fcount,screen_shot_on;
  591.  
  592. int level::tick()
  593. {
  594.   game_object *o,*l=NULL,  // l is last, used for delete
  595.               *cur;        // cur is current object, NULL if object deletes it's self
  596.   int ret=1;
  597.  
  598.   if (profiling())
  599.     profile_reset();
  600.  
  601. /*  // test to see if demo is in sync
  602.   if (current_demo_mode()==DEMO_PLAY)
  603.   {
  604.     if (!rcheck) rcheck=open_file("rcheck","rb");
  605.     long x=rcheck->read_long();
  606.     if (x!=rand_on)
  607.       dprintf("off!\n");
  608.   } else if (current_demo_mode()==DEMO_RECORD)
  609.   {
  610.     if (!rcheck) 
  611.     {
  612.       rcheck=open_file("rcheck","wb");
  613.       rcheck_lp=open_file("rcheck.lp","wb");
  614.     }
  615.     rcheck->write_long(rand_on);
  616.   } else
  617.   {
  618.     if (rcheck)
  619.     {
  620.       delete rcheck;
  621.       rcheck=NULL;
  622.     }
  623.     if (rcheck_lp)
  624.     {
  625.       delete rcheck_lp;
  626.       rcheck_lp=NULL;
  627.     }
  628.   }*/
  629.   
  630.   for (o=first_active;o;)
  631.   {       
  632.     o->last_x=o->x;
  633.     o->last_y=o->y;
  634.     cur=o;
  635.     view *c=o->controller();
  636.     if (!(dev&SUSPEND_MODE) || c)
  637.     {
  638.       o->set_flags(o->flags()&(0xff-FLAG_JUST_HIT-FLAG_JUST_BLOCKED));
  639.  
  640.       if (c)
  641.       {      
  642.     area_controller *a,*smallest=NULL;
  643.     long smallest_size=0xfffffff;
  644.     for (a=area_list;a;a=a->next)
  645.       if (o->x>=a->x && o->y>=a->y && o->x<=a->x+a->w && o->y<=a->y+a->h)
  646.       {
  647.         long size=a->w*a->h;
  648.         if (size<smallest_size)
  649.         {
  650.           smallest=a;
  651.           smallest_size=size;
  652.         }
  653.       }
  654.  
  655.     if (c->local_player())
  656.     {
  657.       if (!shutdown_lighting)       // should we initiate a lighting shutdown?
  658.       {
  659.         if (massive_frame_panic>30)
  660.         {
  661.           shutdown_lighting=100;
  662.           shutdown_lighting_value=c->ambient;
  663.         }
  664.       } else if (massive_frame_panic)  // do we need brighten towards 63?
  665.       {
  666.         if (shutdown_lighting_value<63)
  667.           shutdown_lighting_value++;
  668.       } else if (shutdown_lighting>1)        // delay for some time before turning back on
  669.         shutdown_lighting--;
  670.       else if (shutdown_lighting_value!=c->ambient) // do we need to lower light toward real ambient?
  671.       {
  672.         if (abs(shutdown_lighting_value-c->ambient)<4)
  673.           shutdown_lighting_value=c->ambient;
  674.         else
  675.           if (shutdown_lighting_value<c->ambient)
  676.               shutdown_lighting_value+=4;
  677.         else if (shutdown_lighting_value>c->ambient)
  678.           shutdown_lighting_value-=4;
  679.       } else shutdown_lighting=0;                    // back to normal
  680.     }
  681.  
  682.     if (smallest)
  683.       c->configure_for_area(smallest);
  684.  
  685.  
  686.     o->move(c->x_suggestion,c->y_suggestion,c->b1_suggestion|(c->b2_suggestion<<1)|
  687.         (c->b3_suggestion<<2));
  688.  
  689.     if (o->otype!=current_start_type)
  690.     {
  691.       long fmp=o->fmp();      
  692.       int reduce=figures[o->otype]->morph_power;
  693.       if (reduce)
  694.       {
  695.         fmp-=reduce;
  696.         o->add_power(fmp>>16);
  697.         o->set_fmp(fmp&0xffff);
  698.         if (o->mp()<=0)
  699.         o->morph_into(current_start_type,NULL,-1,9);
  700.       }
  701.     }
  702.  
  703.     l=o;
  704.     o=o->next_active;       
  705.       }
  706.       else if (!o->decide())      // if object returns 0, delete it... I don't like 0's :)
  707.       {
  708.     game_object *p=o;
  709.     o=o->next_active;
  710.     delete_object(p);
  711.     cur=NULL;
  712.       } else 
  713.       {
  714.     o=o->next_active;
  715.     l=o;
  716.       }
  717.     } else
  718.     {
  719.       o=o->next_active;
  720.       l=o;      
  721.     }
  722.  
  723.     clear_tmp();
  724.  
  725.     if (cur)
  726.     {
  727.       point_list *p=cur->current_figure()->hit;  // see if this character is on an attack frame
  728.       if (p && p->tot)
  729.         add_attacker(cur);               // if so add him to attack list for later collision detect
  730.       
  731.       if (cur->hurtable())                    // add to target list if is hurtable
  732.         add_target(cur);
  733.       
  734.     }
  735.  
  736.   }
  737.   tick_panims();
  738.  
  739.   check_collisions();
  740. //  wall_push();
  741.  
  742.   set_tick_counter(tick_counter()+1);
  743.  
  744.   if (sshot_fcount!=-1)
  745.   {
  746.     sshot_fcount++;
  747.     if ((sshot_fcount%70)==0)
  748.     {    
  749.       char name[100];
  750.       sprintf(name,"shot%04d.pcx",screen_shot_on++);
  751.       write_PCX(screen,pal,name);
  752.     }
  753.   }
  754.  
  755.   return ret;
  756. }
  757.  
  758. void level::set_tick_counter(ulong x) 
  759.   ctick=x; 
  760. }
  761.  
  762. void level::draw_areas(view *v)
  763. {
  764.   long sx1,sy1,sx2,sy2;
  765.   area_controller *a=area_list;
  766.   for (;a;a=a->next)
  767.   {
  768.     int c1,c2;
  769.     if (a->active)
  770.     {
  771.       c1=morph_sel_frame_color;
  772.       c2=eh->bright_color();
  773.     } else 
  774.     {
  775.       c2=morph_sel_frame_color;
  776.       c1=eh->bright_color();
  777.     }
  778.     
  779.     the_game->game_to_mouse(a->x,a->y,v,sx1,sy1);
  780.     the_game->game_to_mouse(a->x+a->w,a->y+a->h,v,sx2,sy2);
  781.     screen->rectangle(sx1,sy1,sx2,sy2,c1);
  782.     screen->bar(sx1-1,sy1-1,sx1+1,sy1+1,c2);
  783.     screen->bar(sx2-1,sy2-1,sx2+1,sy2+1,c2);
  784.   }
  785. }
  786.  
  787. void level::draw_objects(view *v)
  788. {
  789.   current_view=v;
  790.   game_object *o=first_active;
  791.   if (dev&MAP_MODE)
  792.   {
  793.     for (;o;o=o->next_active)
  794.       o->map_draw();
  795.   } else
  796.   {
  797.     for (;o;o=o->next_active)
  798.       o->draw();
  799.   }
  800.  
  801.   clear_tmp();
  802. }  
  803.  
  804. void calc_bgsize(unsigned short fgw, unsigned short  fgh, unsigned short  &bgw, unsigned short  &bgh)
  805. {
  806.   bgw=fgw/ASPECT+8;
  807.   bgh=fgh/ASPECT+8;  
  808. }
  809.  
  810.  
  811. void level::set_size(int w, int h) 
  812. {
  813.   if (w*h>200000)
  814.   {
  815.     the_game->show_help(symbol_str("too_big"));
  816.     return ; 
  817.   }
  818.  
  819.   unsigned short *new_fg,*new_bg;
  820.   new_fg=(unsigned short *)jmalloc(w*h*sizeof(short),"Map fg : resized");
  821.   memset(new_fg,0,w*h*sizeof(short));
  822.  
  823.   int x,y,miny=(h<fg_height)? h : fg_height,minx=(w<fg_width)? w : fg_width;
  824.   
  825.   unsigned short nbw,nbh;
  826.   calc_bgsize(w,h,nbw,nbh);
  827.   
  828.   new_bg=(unsigned short *)jmalloc((int)nbw*(int)nbh*sizeof(short),"map bg : resized");
  829.   memset(new_bg,0,(int)nbw*(int)nbh*sizeof(short));
  830.  
  831.   for (y=0;y<miny;y++)
  832.     for (x=0;x<minx;x++)
  833.       new_fg[x+y*w]=get_fg(x,y);
  834.  
  835.   miny=(nbh<bg_height) ? nbh : bg_height;
  836.   minx=(nbw<bg_width) ? nbw : bg_width;
  837.  
  838.   for (y=0;y<miny;y++)
  839.     for (x=0;x<minx;x++)
  840.       new_bg[x+y*nbw]=get_bg(x,y);
  841.  
  842.   jfree(map_fg);
  843.   jfree(map_bg);
  844.   map_fg=new_fg;
  845.   map_bg=new_bg;
  846.   fg_width=w;
  847.   fg_height=h;
  848.   bg_height=nbh;
  849.   bg_width=nbw; 
  850.  
  851.   char msg[80];
  852.   sprintf(msg,"Level %s size now %d %d\n",name(),foreground_width(),foreground_height());
  853.   the_game->show_help(msg);
  854. }
  855.  
  856.  
  857. int locate_var(bFILE *fp, spec_directory *sd, char *str, int size)
  858. {
  859.   spec_entry *se=sd->find(str);
  860.   if (se)
  861.   {
  862.     fp->seek(se->offset,0);
  863.     if (RC_type_size(fp->read_byte())!=size)
  864.       return 0;
  865.     else return 1;
  866.   } 
  867.   return 0;
  868. }
  869.  
  870.  
  871. // load objects assumes current objects have already been disposed of
  872. void level::old_load_objects(spec_directory *sd, bFILE *fp)
  873. {
  874.   spec_entry *se=sd->find("objects");
  875.   total_objs=0;
  876.   first=last=first_active=NULL;
  877.   int i,j;
  878.   if (se)
  879.   {
  880.     fp->seek(se->offset,0);
  881.     /******************************* Read debug info ******************************/
  882.     short old_tot=fp->read_short();  
  883.     unsigned short *o_remap=(unsigned short *)jmalloc(old_tot*2,"obj remap array");    
  884.     char old_name[150];      
  885.     for (i=0;i<old_tot;i++)
  886.     {
  887.       fp->read(old_name,fp->read_byte());    // read the name
  888.       for (o_remap[i]=0xffff,j=0;j<total_objects;j++)  // check for matching current name
  889.       {
  890.     if (!strcmp(old_name,object_names[j]))
  891.           o_remap[i]=j;
  892.       }
  893.     }
  894.  
  895.  
  896.     /***************************** Read state names *********************************/
  897.     int old_stot=fp->read_short();
  898.     unsigned char *s_remap=(unsigned char *)jmalloc(old_stot,"state remap array");
  899.     for (i=0;i<old_stot;i++)
  900.     {
  901.       fp->read(old_name,fp->read_byte());
  902.       s_remap[i]=stopped;           // non exsitant states get mapped into stopped state
  903.       for (j=0;j<MAX_STATE;j++)                  // see if old state exist now
  904.     if (!strcmp(state_names[j],old_name))
  905.          s_remap[i]=j;
  906.     }
  907.     total_objs=fp->read_long();    
  908.  
  909.     se=sd->find("type");
  910.     if (se)
  911.     {
  912.       fp->seek(se->offset,0);
  913.       last=NULL;
  914.       if (fp->read_byte()==RC_S)    //  read type array, this should be type RC_S
  915.       {
  916.     for (i=0;i<total_objs;i++)
  917.     {
  918.       ushort t=fp->read_short();
  919.       game_object *p=new game_object(o_remap[t],1);
  920.       clear_tmp();
  921.       if (!first) first=p; else last->next=p;
  922.       last=p; p->next=NULL;          
  923.     }
  924.  
  925.        
  926.     se=sd->find("state");
  927.     if (se)
  928.     {
  929.       fp->seek(se->offset,0);
  930.       if (fp->read_byte()==RC_S)    //  read state array, this should be type RC_S
  931.       {
  932.         game_object *l=first;
  933.         for (i=0;i<total_objs;i++,l=l->next)
  934.         {
  935.           character_state s=(character_state)s_remap[fp->read_short()];
  936.           if (l->otype!=0xffff)
  937.           {
  938.         if (l->has_sequence((character_state)s))
  939.           l->state=s;
  940.         else l->state=stopped;
  941.         l->current_frame=0;
  942.           }
  943.         }
  944.       }
  945.     }
  946.  
  947.     int frame_var=0;
  948.     int i=0;
  949.     for (;i<TOTAL_OBJECT_VARS;i++)
  950.       if (!strcmp(object_descriptions[i].name,"cur_frame"))
  951.         frame_var=i;
  952.         
  953.     int j=0;
  954.     for (;j<default_simple.total_vars();j++)
  955.     {
  956.       spec_entry *se=sd->find(object_descriptions[j].name);
  957.       if (se)
  958.       {
  959.         fp->seek(se->offset,0);
  960.         int t=object_descriptions[j].type;
  961.         if (fp->read_byte()!=t)
  962.           dprintf("Warning : load level -> var '%s' size changed\n");
  963.         else
  964.         {
  965.           game_object *f=first;
  966.           for (;f;f=f->next)
  967.           {           
  968.         switch (t)
  969.         {
  970.           case RC_C : f->set_var(j,fp->read_byte()); break;
  971.           case RC_S : f->set_var(j,fp->read_short()); break;
  972.           case RC_L : f->set_var(j,fp->read_long()); break;
  973.         }
  974.  
  975.         // check to make sure the frame number is not out of bounds from the time
  976.         // it was last saved
  977.         if (j==frame_var) 
  978.         {
  979.           if (f->otype!=0xffff && f->current_frame>=
  980.               figures[f->otype]->get_sequence(f->state)->length())
  981.             f->current_frame=0;
  982.         }
  983.           } 
  984.         }        
  985.       } else dprintf("Warning : load level -> no previous var %s\n",default_simple.var_name(j));
  986.     }
  987.       }
  988.     }
  989.     
  990.     
  991.  
  992.     jfree(o_remap);
  993.     jfree(s_remap);
  994.   }  
  995.   
  996. }
  997.  
  998.  
  999. // load objects assumes current objects have already been disposed of
  1000. void level::load_objects(spec_directory *sd, bFILE *fp)
  1001. {
  1002.   spec_entry *se=sd->find("object_descripitions"); 
  1003.   total_objs=0;
  1004.   first=last=first_active=NULL;
  1005.   int i,j;
  1006.   if (!se)
  1007.   {
  1008.     old_load_objects(sd,fp);
  1009.     return ;
  1010.   }
  1011.   else if (se)
  1012.   {
  1013.     fp->seek(se->offset,0);
  1014.     short old_tot=fp->read_short();
  1015.     se=sd->find("describe_names");
  1016.     if (!se || !old_tot)
  1017.       return ;
  1018.  
  1019.     unsigned short *o_remap=(unsigned short *)jmalloc(old_tot*2,"obj remap array");    
  1020.     unsigned short *o_backmap=(unsigned short *)jmalloc(total_objects*2,"obj remap array");    
  1021.     memset(o_backmap,0xff,total_objects*2);
  1022.     char old_name[150];      
  1023.     for (i=0;i<old_tot;i++)
  1024.     {
  1025.       fp->read(old_name,fp->read_byte());    // read the name
  1026.       for (o_remap[i]=0xffff,j=0;j<total_objects;j++)  // check for matching current name
  1027.       {
  1028.     if (!strcmp(old_name,object_names[j]))
  1029.     {
  1030.           o_remap[i]=j;
  1031.       o_backmap[j]=i;
  1032.     }
  1033.       }
  1034.     }    
  1035.  
  1036.     se=sd->find("describe_states");
  1037.     if (!se) { jfree(o_remap); jfree(o_backmap); return ; }
  1038.     short **s_remap=(short **)jmalloc(old_tot*sizeof(short *),"big state remap array");
  1039.     short *s_remap_totals=(short *)jmalloc(old_tot*sizeof(short),"big state rmp totals");
  1040.     fp->seek(se->offset,0);
  1041.     int i=0;
  1042.     for (;i<old_tot;i++)
  1043.     {
  1044.       short t=fp->read_short();
  1045.       s_remap_totals[i]=t;
  1046.       if (t)
  1047.       {
  1048.         s_remap[i]=(short *)jmalloc(t*sizeof(short),"state remap");
  1049.     int j=0;
  1050.     for (;j<t;j++)
  1051.       *(s_remap[i]+j)=stopped;    // if no remap found, then go to stopped state
  1052.       }
  1053.       else s_remap[i]=0;
  1054.  
  1055.       int j=0;
  1056.       for (;j<t;j++)
  1057.       {
  1058.     fp->read(old_name,fp->read_byte());
  1059.     int new_type=o_remap[i];    
  1060.     if (new_type<total_objects)     // make sure old object still exsist
  1061.     {
  1062.       int k=0;
  1063.       for (;k<figures[new_type]->ts;k++)
  1064.       {
  1065.         if (figures[new_type]->seq[k] &&
  1066.            !strcmp(lstring_value(symbol_name(figures[new_type]->seq_syms[k])),old_name))
  1067.         *(s_remap[i]+j)=k;
  1068.       }
  1069.     }
  1070.       }
  1071.     }
  1072.  
  1073.     short **v_remap=NULL;
  1074.     short *v_remap_totals=NULL;
  1075.     int load_vars=1;
  1076.     se=sd->find("describe_lvars");
  1077.     if (se)
  1078.     {
  1079.       v_remap=(short **)jmalloc(old_tot*sizeof(short *),"big var remap array");
  1080.       v_remap_totals=(short *)jmalloc(old_tot*sizeof(short),"big var rmp totals");
  1081.  
  1082.       fp->seek(se->offset,0);
  1083.       int i=0;
  1084.       for (;i<old_tot;i++)
  1085.       {
  1086.     short t=fp->read_short();
  1087.     v_remap_totals[i]=t;
  1088.     if (t)
  1089.     {
  1090.       v_remap[i]=(short *)jmalloc(t*sizeof(short),"var remap");
  1091.       memset(v_remap[i],0xff,t*sizeof(short));
  1092.     } else { v_remap[i]=NULL; }
  1093.     int j=0;
  1094.     for (;j<t;j++)
  1095.     {
  1096.       fp->read(old_name,fp->read_byte());
  1097.       int new_type=o_remap[i];
  1098.       if (new_type!=0xffff)        // make sure old object still exsist
  1099.       {
  1100.         int k=0;
  1101.         for (;k<figures[new_type]->tiv;k++)
  1102.         {
  1103.           if (figures[new_type]->vars[k])
  1104.           {
  1105.         if (!strcmp(lstring_value(symbol_name(figures[new_type]->vars[k])),old_name))
  1106.           *(v_remap[i]+j)=figures[new_type]->var_index[k];
  1107.           }
  1108.         }
  1109.       }
  1110.     }
  1111.       }
  1112.       load_vars=1;
  1113.     }
  1114.     
  1115.     se=sd->find("object_list");
  1116.     if (se)
  1117.     {
  1118.       total_objs=fp->read_long();    
  1119.  
  1120.       se=sd->find("type");
  1121.       if (se)
  1122.       {
  1123.     fp->seek(se->offset,0);
  1124.     last=NULL;
  1125.     if (fp->read_byte()==RC_S)    //  read type array, this should be type RC_S
  1126.     {
  1127.       int i=0;
  1128.       for (;i<total_objs;i++)
  1129.       {
  1130.         ushort t=fp->read_short();
  1131.         game_object *p=new game_object(o_remap[t],1);
  1132.         clear_tmp();
  1133.         if (!first) first=p; else last->next=p;
  1134.         last=p; p->next=NULL;          
  1135.       }
  1136.        
  1137.       se=sd->find("state");
  1138.       if (se)
  1139.       {
  1140.         fp->seek(se->offset,0);
  1141.         if (fp->read_byte()==RC_S)    //  read state array, this should be type RC_S
  1142.         {
  1143.           game_object *l=first;
  1144.           for (i=0;i<total_objs;i++,l=l->next)
  1145.           {
  1146.         int st=fp->read_short();
  1147.         if (l->otype==0xffff)
  1148.           l->state=stopped;
  1149.         else
  1150.         {
  1151.           character_state s=(character_state)(*(s_remap[o_backmap[l->otype]]+st));
  1152.           if (l->has_sequence((character_state)s))
  1153.                 l->state=s;
  1154.           else l->state=stopped;
  1155.           l->current_frame=0;
  1156.         }
  1157.           }
  1158.         }
  1159.       }
  1160.     
  1161.       se=sd->find("lvars");
  1162.       if (se && load_vars)
  1163.       {
  1164.         fp->seek(se->offset,0);
  1165.         int abort=0;
  1166.         game_object *o=first;
  1167.         for (;o && !abort;o=o->next)
  1168.         {
  1169.           short ot=fp->read_short();
  1170.           int k=0;
  1171.           for (;k<ot;k++)
  1172.           {
  1173.         if (fp->read_byte()!=RC_L) abort=1;
  1174.         else
  1175.         {
  1176.           long v=fp->read_long();
  1177.           if (o->otype!=0xffff)     // non-exstant object
  1178.           {
  1179.             int remap=*(v_remap[o_backmap[o->otype]]+k);
  1180.             if (remap!=-1 && figures[o->otype]->tiv>=k)
  1181.             {
  1182.               o->lvars[remap]=v;       
  1183.             }
  1184.           }
  1185.         }
  1186.           }
  1187.         }
  1188.       }
  1189.  
  1190.       int frame_var=0;
  1191.       for (i=0;i<TOTAL_OBJECT_VARS;i++)
  1192.         if (!strcmp(object_descriptions[i].name,"cur_frame"))
  1193.           frame_var=i;
  1194.         
  1195.  
  1196.       int j=0;
  1197.       for (;j<default_simple.total_vars();j++)
  1198.       {
  1199.         spec_entry *se=sd->find(object_descriptions[j].name);
  1200.         if (se)
  1201.         {
  1202.           fp->seek(se->offset,0);
  1203.           int t=object_descriptions[j].type;
  1204.           if (fp->read_byte()!=t)
  1205.             dprintf("Warning : load level -> var '%s' size changed\n");
  1206.           else
  1207.           {
  1208.         game_object *f=first;
  1209.         for (;f;f=f->next)
  1210.         {           
  1211.           switch (t)
  1212.           {
  1213.             case RC_C : 
  1214.             { f->set_var(j,fp->read_byte()); } break;
  1215.             case RC_S : 
  1216.             { f->set_var(j,fp->read_short()); } break;
  1217.             case RC_L : 
  1218.             { f->set_var(j,fp->read_long()); } break;
  1219.           }
  1220.           
  1221.           // check to make sure the frame number is not out of bounds from the time
  1222.           // it was last saved
  1223.           if (j==frame_var) 
  1224.           {
  1225.             if (f->otype!=0xffff && f->current_frame>=
  1226.             figures[f->otype]->get_sequence(f->state)->length())
  1227.             f->current_frame=0;
  1228.           }
  1229.         } 
  1230.           }        
  1231.         } else dprintf("Warning : load level -> no previous var %s\n",default_simple.var_name(j));
  1232.       }
  1233.     }
  1234.       }
  1235.     }
  1236.     
  1237.     int k=0;
  1238.     for (;k<old_tot;k++)
  1239.     {
  1240.       if (s_remap_totals[k])
  1241.         jfree(s_remap[k]);
  1242.     }
  1243.  
  1244.     int l=0;
  1245.     for (;l<old_tot;l++)
  1246.     {
  1247.       if (v_remap_totals[l])
  1248.         jfree(v_remap[l]);
  1249.     }
  1250.     jfree(v_remap_totals);
  1251.     jfree(s_remap_totals);
  1252.     jfree(o_remap);
  1253.     jfree(o_backmap);
  1254.     jfree(s_remap);
  1255.     jfree(v_remap);
  1256.   }  
  1257.   
  1258. }
  1259.  
  1260. level::level(spec_directory *sd, bFILE *fp, char *lev_name)
  1261. {
  1262.   spec_entry *e;
  1263.   area_list=NULL;
  1264.  
  1265.   attack_list=NULL;
  1266.   attack_list_size=attack_total=0;
  1267.  
  1268.   target_list=NULL;
  1269.   target_list_size=target_total=0;
  1270.  
  1271.   block_list=NULL;
  1272.   block_list_size=block_total=0;
  1273.  
  1274.   all_block_list=NULL;
  1275.   all_block_list_size=all_block_total=0;
  1276.   first_name=NULL;
  1277.  
  1278.   the_game->need_refresh();
  1279.  
  1280.   char cmd[100];
  1281.   sprintf(cmd,symbol_str("loading"),lev_name);
  1282.   stack_stat stat(cmd);
  1283.   Name=strcpy((char *)jmalloc(strlen(lev_name)+1,"lev name"),lev_name);
  1284.  
  1285.   e=sd->find("first name");
  1286.   if (e)
  1287.   {
  1288.     fp->seek(e->offset,0);
  1289.     int len=fp->read_byte();   // read the length of the string
  1290.     first_name=(char *)jmalloc(len,"level first name");
  1291.     fp->read(first_name,len);    // read the string
  1292.   } else
  1293.   {
  1294.     first_name=(char *)jmalloc(strlen(Name)+1,"level first name");    
  1295.     strcpy(first_name,Name);
  1296.   }
  1297.  
  1298.   e=sd->find("fgmap");
  1299.   int no_fg=0,no_bg=0;
  1300.  
  1301.   if (e)
  1302.   {    
  1303.     fp->seek(e->offset,0);
  1304.     fg_width=fp->read_long();
  1305.     fg_height=fp->read_long();
  1306.     map_fg=(unsigned short *)jmalloc(2*fg_width*fg_height,"Map fg : loaded");
  1307.     fp->read((char *)map_fg,2*fg_width*fg_height);
  1308.     int t=fg_width*fg_height;
  1309.     unsigned short *map=map_fg;
  1310.     while (t) { *map=lstl(*map); map++; t--; }
  1311.   } else
  1312.   {
  1313.     the_game->show_help("Warning foreground map missing");
  1314.     no_fg=1;
  1315.   }
  1316.   stat_man->update(5);
  1317.  
  1318.   e=sd->find("bgmap");
  1319.   if (e)
  1320.   {
  1321.     fp->seek(e->offset,0);
  1322.     bg_width=fp->read_long();
  1323.     bg_height=fp->read_long();
  1324.     map_bg=(unsigned short *)jmalloc(2*bg_width*bg_height,"Map bg : loaded");
  1325.     fp->read((char *)map_bg,2*bg_width*bg_height);
  1326.     int t=bg_width*bg_height;
  1327.     unsigned short *map=map_bg;
  1328.     while (t) { *map=lstl(*map); map++; t--; } 
  1329.   } else
  1330.   {
  1331.     the_game->show_help("Warning background map missing");
  1332.     no_bg=1;
  1333.   }
  1334.  
  1335.   if (no_fg && !no_bg)
  1336.   {
  1337.     fg_width=bg_width;
  1338.     fg_height=bg_height;
  1339.     map_fg=(unsigned short *)jmalloc(2*fg_width*fg_height,"Map fg : loaded");
  1340.     memset(map_fg,0,2*fg_width*fg_height);
  1341.   }
  1342.  
  1343.   if (no_bg)
  1344.   {
  1345.     bg_width=fg_width/8+8;
  1346.     bg_height=fg_height/8+8;
  1347.     map_bg=(unsigned short *)jmalloc(2*bg_width*bg_height,"Map bg : loaded");
  1348.     memset(map_bg,0,2*bg_width*bg_height);
  1349.   }
  1350.   stat_man->update(10);
  1351.  
  1352.   /***************** Check map for non exsistant tiles **************************/
  1353.   long i,j,w;
  1354.   unsigned short *m;  
  1355.   spec_entry *load_all=sd->find("player_info");
  1356.   for (i=0,w=fg_width*fg_height,m=map_fg;i<w;i++,m++)
  1357.   {
  1358.     if (!load_all)
  1359.       (*m)=(*m)&(~0x8000);    // clear the has-seen bit on the tile
  1360.  
  1361.     if (fgvalue(*m)>=nforetiles || foretiles[fgvalue(*m)]<0) 
  1362.       *m=0;  
  1363.   }
  1364.  
  1365.   for (i=0,w=bg_width*bg_height,m=map_bg;i<w;i++,m++)
  1366.   {
  1367.     if ( (bgvalue(*m)>=nbacktiles) || backtiles[bgvalue(*m)]<0) 
  1368.        *m=0;  
  1369.   }
  1370.  
  1371.   load_options(sd,fp);
  1372.   stat_man->update(15);
  1373.  
  1374. //  first=first_active=last=NULL;
  1375.   load_objects(sd,fp);
  1376.   stat_man->update(25);
  1377.  
  1378.   object_node *players,*objs;
  1379.   players=make_player_onodes();
  1380.   objs=make_not_list(players); 
  1381.  
  1382.  
  1383.  
  1384.   read_lights(sd,fp,lev_name);
  1385.   load_links(fp,sd,objs,players);
  1386.   int players_got_loaded=load_player_info(fp,sd,objs);
  1387.  
  1388.  
  1389.   game_object *l=first;
  1390.   for (;l;)
  1391.   {
  1392.     game_object *p=l;
  1393.     l=l->next;
  1394.     if (p->otype==0xffff || p->x<0 || p->y<0)
  1395.       delete_object(p);
  1396.   }
  1397.  
  1398.   load_cache_info(sd,fp);
  1399.  
  1400.   if (!players_got_loaded)
  1401.   {
  1402.     level *old=current_level;
  1403.     current_level=this;
  1404.    
  1405.     object_node *list=NULL;
  1406.     list=make_not_list(list);     // create a list of the object list in case objects change positions
  1407.  
  1408.     object_node *ln=list;
  1409.     for (;ln;ln=ln->next)
  1410.       ln->me->reload_notify();
  1411.     delete_object_list(list);
  1412.  
  1413.     current_level=old;
  1414.  
  1415.     insert_players();
  1416.   }
  1417.  
  1418.   delete_object_list(players);
  1419.   delete_object_list(objs);
  1420.  
  1421. }
  1422.  
  1423.  
  1424. /*
  1425.    [object_descriptions] 2 total_type
  1426.    for(1..total_types)
  1427.    {
  1428.      ["object_names"]  1,(name)
  1429.  
  1430.      ["object_states"]  2(total),<2=number,1,name>
  1431.  
  1432.      ["object_lvars"]   2(total),<1(type),1,name>   
  1433.    }
  1434.  
  1435.   [object_list]
  1436.    4 total_objects    
  1437.    for(1..total_objects)
  1438.    {
  1439.      ["type"]
  1440.      ["state"]
  1441.      ["lvars"]
  1442.      ...
  1443.    }
  1444.  
  1445. */
  1446.  
  1447.  
  1448. void get_prof_assoc_filename(char *filename, char *prof_filename)
  1449. {
  1450.   char *s1,*s2,*dot=NULL;
  1451.   for (s1=filename,s2=prof_filename,dot=NULL;*s1;s1++,s2++)
  1452.   {
  1453.     *s2=*s1;
  1454.     if (*s1=='.') dot=s2;    
  1455.   }
  1456.   if (dot) s2=dot+1;
  1457.  
  1458.   *(s2++)='c'; 
  1459.   *(s2++)='p'; 
  1460.   *(s2++)='f'; 
  1461.   *s2=0;
  1462. }
  1463.  
  1464. void level::level_loaded_notify()
  1465. {
  1466.   char *n;
  1467.   if (first_name)
  1468.     n=first_name;
  1469.   else
  1470.     n=name();
  1471.   if (strstr(n,"levels/level"))
  1472.   {
  1473.     char nm[100];
  1474.     sprintf(nm,"music/abuse%c%c.hmi",n[12],n[13]);
  1475.     bFILE *fp=open_file(nm,"rb");
  1476.     if (fp->open_failure())
  1477.     {
  1478.       delete fp;
  1479.     }
  1480.     else
  1481.     {
  1482.       if (current_song) { current_song->stop(); delete current_song; }
  1483.  
  1484.       delete fp;
  1485.       current_song=new song(nm);
  1486.       current_song->play(music_volume);
  1487.     }
  1488.   }
  1489.   
  1490. /*  if (DEFINEDP(symbol_function(l_level_loaded)))
  1491.   {
  1492.     int sp=current_space;
  1493.     current_space=PERM_SPACE;
  1494.  
  1495.     void *arg_list=NULL;
  1496.     p_ref r1(arg_list);
  1497.     push_onto_list(new_lisp_string(n),arg_list);
  1498.     eval_function((lisp_symbol *)l_level_loaded,arg_list);
  1499.  
  1500.     current_space=sp;
  1501.   } */
  1502. }
  1503.  
  1504.  
  1505. bFILE *level::create_dir(char *filename, int save_all,
  1506.              object_node *save_list, object_node *exclude_list)
  1507. {
  1508.   spec_directory sd;
  1509.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"Copyright 1995 Crack dot Com, All Rights reserved",NULL,0,0));
  1510.   if (first_name)
  1511.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"first name",NULL,strlen(first_name)+2,0));
  1512.     
  1513.  
  1514.  
  1515.   sd.add_by_hand(new spec_entry(SPEC_GRUE_FGMAP,"fgmap",NULL,4+4+fg_width*fg_height*2,0));
  1516.   sd.add_by_hand(new spec_entry(SPEC_GRUE_BGMAP,"bgmap",NULL,4+4+bg_width*bg_height*2,0));
  1517.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"bg_scroll_rate",NULL,1+4*4,0));
  1518.  
  1519.   int ta=0;
  1520.   area_controller *a=area_list;
  1521.   for (;a;a=a->next) ta++;
  1522.  
  1523.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"area_list.v1",NULL,1+ta*(4*11)+4,0));
  1524.  
  1525.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"tick_counter",NULL,1+4,0));
  1526.  
  1527.  
  1528.  
  1529.   // how many object types are we goint to save, use a short to specify how many
  1530.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"object_descripitions",NULL,2,0));
  1531.  
  1532.  
  1533.   int size=0;
  1534.   int i=0;
  1535.   for (;i<total_objects;i++)       // now save the names of the objects so if ordering
  1536.     size+=1+strlen(object_names[i])+1;    // changes in future versions we can adjust in load
  1537.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"describe_names",NULL,size,0));
  1538.  
  1539.  
  1540.   size=0;                                
  1541.   for (i=0;i<total_objects;i++) 
  1542.   {
  1543.     size+=2;  // total number of states
  1544.     int j=0;
  1545.     for (;j<figures[i]->ts;j++)
  1546.       if (figures[i]->seq[j])
  1547.         size+=1+strlen(lstring_value(symbol_name(figures[i]->seq_syms[j])))+1;
  1548.   }
  1549.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"describe_states",NULL,size,0));
  1550.  
  1551.  
  1552.  
  1553.   size=0;
  1554.   for (i=0;i<total_objects;i++) 
  1555.   {
  1556.     size+=2;  // total number of variables
  1557.     int j=0;
  1558.     for (;j<figures[i]->tiv;j++)
  1559.       if (figures[i]->vars[j])
  1560.         size+=1+strlen(lstring_value(symbol_name(figures[i]->vars[j])))+1;
  1561.   }
  1562.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"describe_lvars",NULL,size,0));
  1563.  
  1564.  
  1565.  
  1566.   // how many objects are we goint to save, use a long to specify how many
  1567.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"object_list",NULL,4,0)); 
  1568.   
  1569.   long t=0;
  1570.   object_node *o=save_list;
  1571.   for (;o;o=o->next)
  1572.     t++;
  1573.  
  1574.   // type and state aren't normal records because they will be remapped on loading
  1575.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"type",NULL,1+2*t,0));
  1576.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"state",NULL,1+2*t,0));
  1577.  
  1578.  
  1579.   // now save all the lvars for each object
  1580.   for (size=0,o=save_list;o;o=o->next)
  1581.     size+=figures[o->me->otype]->tv*5+2;
  1582.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"lvars",NULL,size,0));
  1583.  
  1584.  
  1585.   for (i=0;i<TOTAL_OBJECT_VARS;i++)
  1586.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,object_descriptions[i].name,NULL,1+
  1587.               RC_type_size(object_descriptions[i].type)*t,0));
  1588.  
  1589.   add_light_spec(&sd,Name);
  1590.  
  1591.  
  1592.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"object_links",NULL,1+4+total_object_links(save_list)*8,0));
  1593.   sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"light_links",NULL,1+4+total_light_links(save_list)*8,0));
  1594.  
  1595.   if (save_all)
  1596.   {
  1597.     t=0;
  1598.     view *v=player_list;
  1599.     for (;v;v=v->next) t++; 
  1600.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"player_info",NULL,t*4+4,0));
  1601.  
  1602.     int tv=total_view_vars();
  1603.     int i=0;
  1604.     for (;i<tv;i++)
  1605.       sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,get_view_var_name(i),NULL,1+4*t,0));
  1606.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"random_start",NULL,5,0));
  1607.  
  1608.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"weapon_array",NULL,1+4+total_weapons*4*t,0));
  1609.  
  1610.     int name_len=0;
  1611.     for (v=player_list;v;v=v->next)
  1612.       name_len+=strlen(v->name)+2;
  1613.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"player_names",NULL,name_len,0));
  1614.  
  1615.     sd.add_by_hand(new spec_entry(SPEC_IMAGE,"thumb nail",NULL,4+160*(100+eh->font()->height()*2),0));
  1616.   }
  1617.  
  1618.   sd.calc_offsets();
  1619.  
  1620.   return sd.write(filename);
  1621. }
  1622.  
  1623. void scale_put(image *im, image *screen, int x, int y, short new_width, short new_height);
  1624.  
  1625. void level::write_thumb_nail(bFILE *fp, image *im)
  1626. {
  1627.   image *i=new image(160,100+eh->font()->height()*2);
  1628.   i->clear();
  1629.   scale_put(im,i,0,0,160,100);
  1630.   if (first_name)
  1631.     eh->font()->put_string(i,80-strlen(first_name)*eh->font()->width()/2,100,first_name);
  1632.  
  1633.   time_t t;
  1634.   t=time(NULL);
  1635.   char buf[80];
  1636.  
  1637.   strftime(buf,80,"%T %A %B %d",localtime(&t));  
  1638.   eh->font()->put_string(i,80-strlen(buf)*eh->font()->width()/2,100+eh->font()->height(),buf);
  1639.  
  1640.   fp->write_short(i->width());
  1641.   fp->write_short(i->height());
  1642.   int y=0;
  1643.   for (;y<i->height();y++)
  1644.     fp->write(i->scan_line(y),i->width());
  1645.  
  1646.   delete i;
  1647. }
  1648.  
  1649. void level::write_player_info(bFILE *fp, object_node *save_list)
  1650. {
  1651.   long t=0;
  1652.   view *v=player_list;
  1653.   for (;v;v=v->next) t++; 
  1654.   fp->write_long(t);
  1655.  
  1656.   for (v=player_list;v;v=v->next)
  1657.     fp->write_long(object_to_number_in_list(v->focus,save_list));
  1658.  
  1659.   int tv=total_view_vars();
  1660.   int i=0;
  1661.   for (;i<tv;i++)
  1662.   {
  1663.     fp->write_byte(RC_L);
  1664.     for (v=player_list;v;v=v->next)
  1665.       fp->write_long(v->get_view_var_value(i));
  1666.   }
  1667.  
  1668.   fp->write_byte(RC_L);
  1669.   fp->write_long(rand_on);
  1670.  
  1671.   fp->write_byte(RC_L);
  1672.   fp->write_long(total_weapons);
  1673.   for (v=player_list;v;v=v->next)
  1674.     for (i=0;i<total_weapons;i++)
  1675.       fp->write_long(v->weapons[i]);
  1676.  
  1677.   for (v=player_list;v;v=v->next)
  1678.   {
  1679.     int len=strlen(v->name)+1;
  1680.     fp->write_byte(len);
  1681.     fp->write(v->name,len);
  1682.   }
  1683. }
  1684.  
  1685.  
  1686. int level::load_player_info(bFILE *fp, spec_directory *sd, object_node *save_list)
  1687. {
  1688.   int ret;
  1689.   spec_entry *se=sd->find("player_info");
  1690.   if (se)
  1691.   {
  1692.     fp->seek(se->offset,0);
  1693.  
  1694.     int set_first_view=0;
  1695.     if (the_game->first_view==player_list) set_first_view=1;
  1696.     int my_player_number=-1;
  1697.  
  1698.     view *v=player_list;
  1699.     for (;v;v=v->next)
  1700.     { v->suggest.send_view=0;
  1701.       v->suggest.send_weapon_change=0;
  1702.     }
  1703.  
  1704.     for (v=player_list;v;v=v->next)
  1705.       if (v->local_player()) 
  1706.          my_player_number=v->player_number;
  1707.  
  1708.     while (player_list)    // delete all of the views (they will get recreated)
  1709.     {
  1710.       v=player_list;
  1711.       if (v->focus)
  1712.       {
  1713.         if (v->focus->controller())
  1714.          v->focus->set_controller(NULL);
  1715.     delete v->focus;
  1716.       }
  1717.  
  1718.       player_list=player_list->next;
  1719.       delete v;
  1720.     }
  1721.  
  1722.     long total_players=fp->read_long();
  1723.     view *last;
  1724.     int i=0;
  1725.     for (;i<total_players;i++)    
  1726.     {
  1727.       game_object *o=number_to_object_in_list(fp->read_long(),save_list);
  1728.       v=new view(o,NULL,0);
  1729.       if (o) o->set_controller(v);
  1730.       if (player_list)
  1731.         last->next=v;
  1732.       else player_list=v;
  1733.       last=v;
  1734.     }
  1735.     if (set_first_view)
  1736.       the_game->first_view=player_list;
  1737.     
  1738.     for (i=0;i<total_view_vars();i++)
  1739.     {
  1740.       char *find_name=get_view_var_name(i);
  1741.       se=sd->find(find_name);
  1742.  
  1743.       if (se)
  1744.       {
  1745.     fp->seek(se->offset,0);
  1746.     if (fp->read_byte()==RC_L)
  1747.     {
  1748.       for (v=player_list;v;v=v->next)
  1749.             v->set_view_var_value(i,fp->read_long());
  1750.     }
  1751.       } else 
  1752.       {
  1753.     for (v=player_list;v;v=v->next)
  1754.         v->set_view_var_value(i,0);
  1755.       }
  1756.     }
  1757.  
  1758.     se=sd->find("random_start");      // start of index into random table
  1759.     if (se)
  1760.     {
  1761.       fp->seek(se->offset,0);
  1762.       if (fp->read_byte()==RC_L)
  1763.         rand_on=fp->read_long();
  1764.     } else rand_on=0;
  1765.  
  1766.     se=sd->find("weapon_array");
  1767.     if (se)
  1768.     {
  1769.       fp->seek(se->offset,0);
  1770.       if (fp->read_byte()==RC_L)
  1771.       {
  1772.     long m=fp->read_long();  // read how many weapons exsisted when last saved
  1773.     int i;
  1774.     for (v=player_list;v;v=v->next)      
  1775.     {
  1776.       for (i=0;i<m;i++)
  1777.       {
  1778.         long x=fp->read_long();
  1779.         if (i<total_weapons)
  1780.         {
  1781.           v->weapons[i]=x;
  1782.           v->last_weapons[i]=x;
  1783.         }
  1784.       }
  1785.     }
  1786.       }
  1787.     }  else 
  1788.     { 
  1789.       for (v=player_list;v;v=v->next)      
  1790.       {
  1791.     memset(v->last_weapons,0xff,total_weapons*sizeof(long));
  1792.     memset(v->weapons,0xff,total_weapons*sizeof(long));
  1793.       }
  1794.     }
  1795.  
  1796.     se=sd->find("player_names");
  1797.     if (se)
  1798.     {
  1799.       fp->seek(se->offset,0);
  1800.       for (v=player_list;v;v=v->next)      
  1801.       {
  1802.     uchar len=fp->read_byte();
  1803.     fp->read(v->name,len);
  1804.       }
  1805.     }
  1806.  
  1807.     ret=1;
  1808.     recalc_local_view_space();
  1809.     
  1810.   } else 
  1811.   {
  1812.     void *fun=make_find_symbol("set_player_defaults");
  1813.     if (DEFINEDP(symbol_function(fun)))
  1814.     {      
  1815.       view *f;
  1816.       game_object *o=current_object;
  1817.       for (f=player_list;f;f=f->next)
  1818.       {
  1819.     if (f->focus)
  1820.     {
  1821.       current_object=f->focus;
  1822.       void *m=mark_heap(TMP_SPACE);
  1823.       eval_function((lisp_symbol *)fun,NULL);
  1824.       restore_heap(m,TMP_SPACE);
  1825.     }
  1826.       }    
  1827.       current_object=o;
  1828.     }
  1829.     ret=0;
  1830.   }
  1831.  
  1832.   view *vw;
  1833.   for (vw=player_list;vw;vw=vw->next)
  1834.   {
  1835.     if (total_weapons && !vw->has_weapon(vw->current_weapon))
  1836.     {
  1837.       vw->suggest.send_weapon_change=1;
  1838.       vw->suggest.new_weapon=0;      
  1839.     }
  1840.   }
  1841.  
  1842.   return ret;
  1843. }
  1844.  
  1845.  
  1846. void level::write_objects(bFILE *fp, object_node *save_list)
  1847. {
  1848.   // record information in the file about what the data structures look like
  1849.   // right now, so if they change later, they don't get get screwed up
  1850.   fp->write_short(total_objects);   // mark how many objects we know about right now  
  1851.  
  1852.   int i=0;
  1853.   for (;i<total_objects;i++)   // loop through all the object types we know of
  1854.   {    
  1855.     fp->write_byte(strlen(object_names[i])+1);                    // sizeof name    
  1856.     fp->write(object_names[i],strlen(object_names[i])+1);      // write object name
  1857.   }
  1858.     
  1859.  
  1860.   // write state numbers and names for each object
  1861.   for (i=0;i<total_objects;i++)
  1862.   {
  1863.     int total=0;
  1864.     int j=0;
  1865.     for (;j<figures[i]->ts;j++)
  1866.       if (figures[i]->seq[j]) total++;
  1867.     fp->write_short(total);
  1868.  
  1869.     for (j=0;j<figures[i]->ts;j++)
  1870.       if (figures[i]->seq[j])
  1871.       {
  1872.     char *state_name=lstring_value(symbol_name(figures[i]->seq_syms[j]));
  1873.     fp->write_byte(strlen(state_name)+1);
  1874.     fp->write(state_name,strlen(state_name)+1);
  1875.       }
  1876.   }
  1877.  
  1878.   
  1879.   // write object lvar names
  1880.   for (i=0;i<total_objects;i++)
  1881.   {
  1882.     fp->write_short(figures[i]->tv);
  1883.     int j,x;
  1884.     
  1885.     for (x=0;x<figures[i]->tv;x++)
  1886.     {
  1887.       for (j=0;j<figures[i]->tiv;j++)
  1888.       {
  1889.         if (figures[i]->vars[j] && figures[i]->var_index[j]==x)
  1890.     {
  1891.       char *var_name=lstring_value(symbol_name(figures[i]->vars[j]));
  1892.       fp->write_byte(strlen(var_name)+1);
  1893.       fp->write(var_name,strlen(var_name)+1);
  1894.     }
  1895.       }
  1896.     }
  1897.   }
  1898.   
  1899.   long t=0;
  1900.   object_node *o=save_list;
  1901.   for (;o;o=o->next) t++;
  1902.   fp->write_long(t);
  1903.  
  1904.  
  1905.   fp->write_byte(RC_S);                                    // save type info for each record
  1906.   for (o=save_list;o;o=o->next) fp->write_short(o->me->type());    
  1907.  
  1908.   fp->write_byte(RC_S);                                    // save state info for each record
  1909.   for (o=save_list;o;o=o->next) fp->write_short(o->me->reduced_state());
  1910.  
  1911.   for (o=save_list;o;o=o->next)                            // save lvars
  1912.   {
  1913.     fp->write_short(figures[o->me->otype]->tv);
  1914.     for (i=0;i<figures[o->me->otype]->tv;i++) 
  1915.     {
  1916.       fp->write_byte(RC_L);                           // for now the only type allowed is long
  1917.       fp->write_long(o->me->lvars[i]);
  1918.     }
  1919.   }
  1920.  
  1921.   for (i=0;i<default_simple.total_vars();i++)
  1922.   {
  1923.     int t=object_descriptions[i].type;
  1924.     fp->write_byte(t);
  1925.     for (o=save_list;o;o=o->next)
  1926.     {
  1927.       switch (t)
  1928.       {     
  1929.     case RC_C :
  1930.     { fp->write_byte(o->me->get_var(i)); } break;
  1931.     case RC_S :
  1932.     { fp->write_short(o->me->get_var(i)); } break;
  1933.     case RC_L :
  1934.     { fp->write_long(o->me->get_var(i)); } break;
  1935.       }
  1936.     }
  1937.   }
  1938. }
  1939.  
  1940.  
  1941. long level::total_object_links(object_node *list)
  1942. {
  1943.   long tl=0;
  1944.   for (object_node *o=list;o;o=o->next)
  1945.     tl+=o->me->total_objects();
  1946.   return tl;
  1947. }
  1948.  
  1949. long level::total_light_links(object_node *list)
  1950. {
  1951.   long tl=0;
  1952.   for (object_node *o=list;o;o=o->next)
  1953.     tl+=o->me->total_lights();
  1954.   return tl;
  1955. }
  1956.  
  1957. void level::write_links(bFILE *fp, object_node *save_list, object_node *exclude_list)
  1958. {
  1959.   fp->write_byte(RC_L);  
  1960.   fp->write_long(total_object_links(save_list));
  1961.  
  1962.   int x=1;
  1963.   object_node *o=save_list;
  1964.  
  1965.   for (;o;o=o->next,x++)
  1966.   {
  1967.     int i=0;
  1968.     for (;i<o->me->total_objects();i++)
  1969.     {
  1970.       fp->write_long(x);
  1971.       long x=object_to_number_in_list(o->me->get_object(i),save_list); 
  1972.       if (x)
  1973.         fp->write_long(x);
  1974.       else                            // save links to excluded items as negative
  1975.         fp->write_long((long)(-(object_to_number_in_list(o->me,exclude_list))));
  1976.     }
  1977.   }
  1978.  
  1979.   fp->write_byte(RC_L);  
  1980.   fp->write_long(total_light_links(save_list));
  1981.  
  1982.   x=1;
  1983.   for (o=save_list;o;o=o->next,x++)
  1984.   {
  1985.     int i=0;
  1986.     for (;i<o->me->total_lights();i++)
  1987.     {
  1988.       fp->write_long(x);
  1989.       fp->write_long(light_to_number(o->me->get_light(i)));
  1990.     }
  1991.   }
  1992.  
  1993. }
  1994.  
  1995.  
  1996. void level::load_links(bFILE *fp, spec_directory *sd, 
  1997.                object_node *save_list, object_node *exclude_list)
  1998. {
  1999.   spec_entry *se=sd->find("object_links");
  2000.   if (se)
  2001.   {
  2002.     fp->seek(se->offset,0);
  2003.     if (fp->read_byte()==RC_L)
  2004.     {
  2005.       long t=fp->read_long();
  2006.       while (t)
  2007.       {
  2008.     long x1=fp->read_long();
  2009.     CONDITION(x1>=0,"expected x1 for object link to be > 0\n");
  2010.     long x2=fp->read_long();
  2011.     game_object *p,*q=number_to_object_in_list(x1,save_list);
  2012.     if (x2>0)
  2013.       p=number_to_object_in_list(x2,save_list);
  2014.     else p=number_to_object_in_list(-x2,exclude_list);
  2015.     if (q)
  2016.       q->add_object(p);
  2017.     else dprintf("bad object link\n");
  2018.  
  2019.     t--;
  2020.       } 
  2021.     }
  2022.   }
  2023.  
  2024.   se=sd->find("light_links");
  2025.   if (se)
  2026.   {
  2027.     fp->seek(se->offset,0);
  2028.     if (fp->read_byte()==RC_L)
  2029.     {
  2030.       long t=fp->read_long();
  2031.       while (t)
  2032.       {
  2033.     long x1=fp->read_long();
  2034.     long x2=fp->read_long();
  2035.     game_object *p=number_to_object_in_list(x1,save_list);
  2036.     if (p)
  2037.       p->add_light(number_to_light(x2));
  2038.     else dprintf("bad object/light link\n");
  2039.     t--;
  2040.       } 
  2041.     }
  2042.   }
  2043.  
  2044. }
  2045.  
  2046.  
  2047. void level::write_options(bFILE *fp)
  2048. {
  2049.   // save background scroll rate
  2050.   fp->write_byte(RC_L);
  2051.   fp->write_long(bg_xmul);
  2052.   fp->write_long(bg_xdiv);
  2053.   fp->write_long(bg_ymul);
  2054.   fp->write_long(bg_ydiv);
  2055.  
  2056.   fp->write_byte(RC_L);
  2057.   int ta=0;
  2058.   area_controller *a=area_list;
  2059.   for (;a;a=a->next) ta++;
  2060.   fp->write_long(ta);
  2061.   for (a=area_list;a;a=a->next)
  2062.   {
  2063.     fp->write_long(a->x);
  2064.     fp->write_long(a->y);
  2065.     fp->write_long(a->w);
  2066.     fp->write_long(a->h);
  2067.     fp->write_long(a->active);
  2068.  
  2069.     fp->write_long(a->ambient);
  2070.     fp->write_long(a->view_xoff);
  2071.     fp->write_long(a->view_yoff);
  2072.     fp->write_long(a->ambient_speed);
  2073.     fp->write_long(a->view_xoff_speed);
  2074.     fp->write_long(a->view_yoff_speed);
  2075.   }
  2076.   fp->write_byte(RC_L);
  2077.   fp->write_long(tick_counter());
  2078. }
  2079.  
  2080. void level::load_options(spec_directory *sd, bFILE *fp)
  2081. {
  2082.   spec_entry *se=sd->find("bg_scroll_rate");
  2083.   if (se)
  2084.   {
  2085.     fp->seek(se->offset,0);
  2086.     if (fp->read_byte()!=RC_L)
  2087.     { bg_xmul=bg_ymul=1; bg_xdiv=bg_ydiv=8; }
  2088.     else
  2089.     {
  2090.       bg_xmul=fp->read_long();
  2091.       bg_xdiv=fp->read_long();
  2092.       bg_ymul=fp->read_long();
  2093.       bg_ydiv=fp->read_long();
  2094.     }
  2095.   } else { bg_xmul=bg_ymul=1; bg_xdiv=bg_ydiv=8; }
  2096.  
  2097.   se=sd->find("area_list.v1");
  2098.   if (se)
  2099.   {
  2100.     fp->seek(se->offset,0);
  2101.     if (fp->read_byte()==RC_L)
  2102.     {
  2103.       area_controller *l=NULL,*p;
  2104.       long ta=fp->read_long();
  2105.       int i=0;
  2106.       for (;i<ta;i++)
  2107.       {
  2108.     long x,y,w,h;
  2109.     x=fp->read_long();
  2110.     y=fp->read_long();
  2111.     w=fp->read_long();
  2112.     h=fp->read_long();    
  2113.     p=new area_controller(x,y,w,h,NULL);
  2114.     if (l) l->next=p;
  2115.     else area_list=p;
  2116.     l=p;
  2117.     p->active=fp->read_long();
  2118.     p->ambient=fp->read_long();
  2119.     p->view_xoff=fp->read_long();
  2120.     p->view_yoff=fp->read_long();
  2121.     p->ambient_speed=fp->read_long();
  2122.     p->view_xoff_speed=fp->read_long();
  2123.     p->view_yoff_speed=fp->read_long();
  2124.       }
  2125.     }
  2126.   }
  2127.  
  2128.   se=sd->find("tick_counter");
  2129.   if (se)
  2130.   {
  2131.     fp->seek(se->offset,0);
  2132.     if (fp->read_byte()==RC_L)    
  2133.       set_tick_counter(fp->read_long());
  2134.     else set_tick_counter(0);
  2135.   } else set_tick_counter(0);
  2136. }
  2137.  
  2138.  
  2139. void level::write_cache_prof_info()
  2140. {
  2141.   if (cash.prof_is_on())
  2142.   {
  2143.     char pf_name[100];
  2144.     if (first_name)
  2145.       get_prof_assoc_filename(first_name,pf_name);
  2146.     else
  2147.       get_prof_assoc_filename(Name,pf_name);
  2148.  
  2149.  
  2150.     spec_directory sd;
  2151.     sd.add_by_hand(new spec_entry(SPEC_DATA_ARRAY,"cache profile info",NULL,cash.prof_size(),0));
  2152.     sd.calc_offsets();
  2153.     jFILE *fp2=sd.write(pf_name);
  2154.     if (!fp2)
  2155.       the_game->show_help("Unable to open cache profile output file");
  2156.     else
  2157.     {
  2158.       cash.prof_write(fp2);
  2159.       delete fp2;
  2160.     }
  2161.     sd.delete_entries();
  2162.   }
  2163.  
  2164. }
  2165.  
  2166. void level::load_cache_info(spec_directory *sd, bFILE *fp)
  2167. {
  2168.   if (!DEFINEDP(symbol_value(l_empty_cache)) || !symbol_value(l_empty_cache))
  2169.   {
  2170.     char pf_name[100];
  2171.     if (first_name)
  2172.       get_prof_assoc_filename(first_name,pf_name);  // get cache info from orignal filename if this is a savegame
  2173.     else
  2174.       get_prof_assoc_filename(Name,pf_name);
  2175.  
  2176.  
  2177.     cash.load_cache_prof_info(pf_name,this);
  2178.   }
  2179. }
  2180.  
  2181.  
  2182. int level::save(char *filename, int save_all)
  2183. {  
  2184.   if (!save_all && DEFINEDP(symbol_value(l_keep_backup)) &&
  2185.       symbol_value(l_keep_backup))                        // make a backup 
  2186.   {
  2187.     bFILE *fp=open_file(filename,"rb");                   // do file already exsist?
  2188.     if (!fp->open_failure())
  2189.     {
  2190.       unlink("levsave.bak");
  2191.       bFILE *bk=open_file("levsave.bak","wb");
  2192.       if (bk->open_failure())
  2193.         dprintf("unable to open backup file levsave.bak");
  2194.       else
  2195.       {     
  2196.                 long size=fp->file_size();
  2197.                 uchar *buf=(uchar *)jmalloc(0x1000,"copy buf");
  2198.                 int tr=1;
  2199.                 while (size && tr)
  2200.                 {
  2201.                   int tr=fp->read(buf,0x1000);
  2202.                   if (tr)
  2203.                   tr=bk->write(buf,tr);      
  2204.                   size-=tr;
  2205.                 }
  2206.                 jfree(buf);
  2207.       }
  2208.       delete bk;
  2209. #ifndef __POWERPC__
  2210.       chmod("levsave.bak",S_IRWXU | S_IRWXG | S_IRWXO);
  2211. #endif
  2212.     }
  2213.     delete fp;
  2214.   }
  2215.  
  2216.   
  2217.   // if we are not doing a savegame then change the first_name to this name
  2218.   if (!save_all)
  2219.   {
  2220.     if (first_name) jfree(first_name);
  2221.     first_name=(char *)jmalloc(strlen(filename)+1,"level first name");
  2222.     strcpy(first_name,filename);
  2223.   }
  2224.   
  2225.  
  2226.   
  2227.   object_node *players,*objs;
  2228.   if (save_all)
  2229.     players=NULL;
  2230.   else
  2231.     players=make_player_onodes();
  2232.  
  2233.   objs=make_not_list(players);     // negate the above list
  2234.  
  2235.   bFILE *fp=create_dir(filename,save_all,objs,players);
  2236.   if (!fp->open_failure())
  2237.   {
  2238.     if (first_name)
  2239.     {
  2240.       fp->write_byte(strlen(first_name)+1);
  2241.       fp->write(first_name,strlen(first_name)+1);
  2242.     } else 
  2243.     {
  2244.       fp->write_byte(1);
  2245.       fp->write_byte(0);
  2246.     }
  2247.  
  2248.     fp->write_long(fg_width);
  2249.     fp->write_long(fg_height);
  2250.  
  2251.     int t=fg_width*fg_height;
  2252.     ushort *rm=map_fg;    
  2253.     for (;t;t--,rm++) 
  2254.     {
  2255.       ushort x=*rm;
  2256.       x=lstl(x);            // convert to intel endianess
  2257.       *rm=x;
  2258.     }
  2259.  
  2260.     fp->write((char *)map_fg,2*fg_width*fg_height);
  2261.     t=fg_width*fg_height;
  2262.     rm=map_fg;
  2263.     for (;t;t--,rm++) 
  2264.     {
  2265.       ushort x=*rm;
  2266.       x=lstl(x);            // convert to intel endianess
  2267.       *rm=x;
  2268.     }
  2269.  
  2270.  
  2271.     fp->write_long(bg_width);
  2272.     fp->write_long(bg_height);
  2273.     t=bg_width*bg_height;
  2274.     rm=map_bg;
  2275.     
  2276.     for (;t;t--,rm++) 
  2277.     {
  2278.       ushort x=*rm;
  2279.       x=lstl(x);            // convert to intel endianess
  2280.       *rm=x;
  2281.     }
  2282.  
  2283.     fp->write((char *)map_bg,2*bg_width*bg_height); 
  2284.     rm=map_bg;
  2285.     t=bg_width*bg_height;
  2286.  
  2287.     for (;t;t--,rm++) 
  2288.     {
  2289.       ushort x=*rm;
  2290.       x=lstl(x);            // convert to intel endianess
  2291.       *rm=x;
  2292.     }
  2293.  
  2294.  
  2295.     write_options(fp);
  2296.  
  2297.  
  2298.  
  2299.     write_objects(fp,objs);
  2300.     write_lights(fp);
  2301.     write_links(fp,objs,players);
  2302.     if (save_all)
  2303.     {
  2304.       write_player_info(fp,objs);
  2305.       write_thumb_nail(fp,screen);
  2306.     }
  2307.    
  2308.  
  2309.     delete fp;
  2310. #ifndef __POWERPC__
  2311.     chmod(filename,S_IRWXU | S_IRWXG | S_IRWXO);
  2312. #endif
  2313.     write_cache_prof_info();
  2314.   } else 
  2315.   {
  2316.     the_game->show_help("Unable to open file for saving\n");
  2317.     delete fp;
  2318.     return 0;
  2319.   }
  2320.  
  2321.   delete_object_list(players);
  2322.   delete_object_list(objs);
  2323.  
  2324.   return 1;
  2325. }
  2326.  
  2327. level::level(int width, int height, char *name)
  2328. {
  2329.   the_game->need_refresh();
  2330.   area_list=NULL;
  2331.   set_tick_counter(0);
  2332.  
  2333.   attack_list=NULL;
  2334.   attack_list_size=attack_total=0;
  2335.  
  2336.   target_list=NULL;
  2337.   target_list_size=target_total=0;
  2338.  
  2339.   block_list=NULL;
  2340.   block_list_size=block_total=0;
  2341.  
  2342.   all_block_list=NULL;
  2343.   all_block_list_size=all_block_total=0;
  2344.  
  2345.   Name=NULL;
  2346.   first_name=NULL;
  2347.  
  2348.   set_name(name);
  2349.   first=first_active=NULL;
  2350.   
  2351.   fg_width=width;
  2352.   fg_height=height;
  2353.   calc_bgsize(fg_width,fg_height,bg_width,bg_height);
  2354.   
  2355.   map_bg=(unsigned short *)jmalloc(sizeof(short)*bg_width*bg_height,"map bg");
  2356.   map_fg=(unsigned short *)jmalloc(sizeof(short)*fg_width*fg_height,"map fg");
  2357.  
  2358.  
  2359.  
  2360.   memset(map_bg,0,sizeof(short)*bg_width*bg_height);
  2361.   memset(map_fg,0,sizeof(short)*fg_width*fg_height);
  2362.  
  2363.   int i;  
  2364.   for (i=0;i<fg_width;i++)
  2365.   {    
  2366.     map_fg[i]=1;
  2367.     map_fg[fg_width*(fg_height-1)+i]=1;
  2368.   }
  2369.   for (i=0;i<fg_height;i++)
  2370.   {    
  2371.     map_fg[fg_width*i]=1;
  2372.     map_fg[fg_width*i+fg_width-1]=1;
  2373.   }
  2374.   
  2375.   total_objs=0;  
  2376.   insert_players();
  2377. }
  2378.  
  2379.  
  2380. void level::add_object(game_object *new_guy)
  2381. {
  2382.   total_objs++;
  2383.   new_guy->next=NULL;
  2384.   if (figures[new_guy->otype]->get_cflag(CFLAG_ADD_FRONT))
  2385.   {
  2386.     if (!first)
  2387.       first=new_guy;
  2388.     else
  2389.       last->next=new_guy;
  2390.     last=new_guy;
  2391.   } else
  2392.   {
  2393.     if (!first)
  2394.       last=first=new_guy;
  2395.     else
  2396.     {
  2397.       new_guy->next=first;
  2398.       first=new_guy;
  2399.     }
  2400.   }
  2401. }
  2402.  
  2403. void level::add_object_after(game_object *new_guy,game_object *who)
  2404. {
  2405.   if (!who) add_object(new_guy);
  2406.   else
  2407.   {
  2408.     total_objs++;
  2409.     if (who==last) last=new_guy;
  2410.     new_guy->next=who->next;
  2411.     who->next=new_guy;
  2412.   }
  2413. }
  2414.  
  2415. void level::delete_object(game_object *who)
  2416. {
  2417.   remove_object(who);
  2418.   delete who;
  2419. }
  2420.  
  2421. void level::remove_block(game_object *who)
  2422. {
  2423.   int i=0,j;
  2424.   game_object **o=block_list;
  2425.   for (;i<block_total;i++)
  2426.   {
  2427.     if (*o==who)        // is this object in the block list?
  2428.     {
  2429.       block_total--;    // squish the block list in
  2430.       o++;
  2431.       for (j=i;j<block_total;j++)
  2432.         block_list[j]=block_list[j+1];
  2433.     } else o++;    
  2434.   }
  2435. }
  2436.  
  2437.  
  2438. // searches through the all_block list for who and if it finds it deletes it
  2439. void level::remove_all_block(game_object *who)
  2440. {
  2441.   int i=0,j;
  2442.   game_object **o=all_block_list;
  2443.   for (;i<all_block_total;i++)
  2444.   {
  2445.     if (*o==who)        // is this object in the block list?
  2446.     {
  2447.       all_block_total--;    // squish the block list in
  2448.       o++;
  2449.       for (j=i;j<all_block_total;j++)
  2450.         all_block_list[j]=all_block_list[j+1];
  2451.     } else o++;    
  2452.   }
  2453. }
  2454.  
  2455. void level::remove_object(game_object *who)
  2456. {
  2457.   if (dev_cont)
  2458.     dev_cont->notify_deleted_object(who);
  2459.  
  2460.   if (who==first)
  2461.   {
  2462.     if (who==last) last=NULL;
  2463.     first=first->next;
  2464.   }
  2465.   else
  2466.   {
  2467.     game_object *o=first;
  2468.     for (;o && o->next!=who;o=o->next);
  2469.     if (o)
  2470.     {
  2471.       o->next=who->next;
  2472.       if (!o->next) last=o;
  2473.     }
  2474.     else return ;     // if object is not in level, don't try to do anything else
  2475.   }
  2476.   total_objs--;
  2477.  
  2478.  
  2479.   if (first_active==who) 
  2480.     first_active=who->next_active;
  2481.   else
  2482.   {
  2483.     game_object *o=first_active;
  2484.     for (;o && o->next_active!=who;o=o->next_active);
  2485.     if (o)
  2486.       o->next_active=who->next_active;
  2487.   }
  2488.  
  2489.   if (who->flags()&KNOWN_FLAG)
  2490.   {
  2491.     game_object *o=first;
  2492.     for (;o;o=o->next)
  2493.     {
  2494.       int t=o->total_objects();
  2495.       int i=0;
  2496.       for (;i<t;i++)
  2497.         if (o->get_object(i)==who)
  2498.     {
  2499.       o->remove_object(who);
  2500.       t=o->total_objects();
  2501.     }
  2502.     }
  2503.   }
  2504.  
  2505.   if (who->otype<0xffff)
  2506.   {
  2507.     if (who->can_block())  // remove object from block list and all_block if nessasary
  2508.     {
  2509.       remove_block(who);
  2510.       remove_all_block(who);
  2511.     } else if (who->hurtable()) 
  2512.       remove_all_block(who);
  2513.   }
  2514.  
  2515.  
  2516.   int t=who->total_objects();
  2517.   while (t) { who->remove_object(who->get_object(0)); t--; }
  2518.  
  2519.   t=who->total_lights();
  2520.   while (t) { who->remove_light(who->get_light(0)); t--; }
  2521. }
  2522.  
  2523. void level::to_front(game_object *o)  // move to end of list, so we are drawn last, therefore top 
  2524. {
  2525.   if (o==last) return ;
  2526.   first_active=NULL;     // make sure nothing goes screwy with the active list
  2527.  
  2528.   if (o==first)  
  2529.     first=first->next;  
  2530.   else
  2531.   {
  2532.     game_object *w=first;
  2533.     for (;w && w->next!=o;w=w->next);
  2534.     if (!w) return ;
  2535.     w->next=o->next;
  2536.   }
  2537.  
  2538.   last->next=o;
  2539.   o->next=NULL;
  2540.   last=o;
  2541. }
  2542.  
  2543. void level::to_back(game_object *o)   // to make the character drawn in back, put at front of list
  2544. {  
  2545.   if (o==first) return;
  2546.   first_active=NULL;     // make sure nothing goes screwy with the active list  
  2547.   
  2548.   game_object *w=first;
  2549.   for (;w && w->next!=o;w=w->next);
  2550.   if (!w) return;
  2551.   if (last==o)
  2552.     last=w;
  2553.   w->next=o->next;
  2554.   o->next=first;
  2555.   first=o;
  2556. }
  2557.  
  2558.  
  2559. game_object *level::find_self(game_object *me)
  2560. {
  2561.   return me;
  2562. }
  2563.  
  2564. game_object *level::find_object(long x, long y)
  2565. {
  2566.   long x1,y1,x2,y2;  
  2567.   game_object *o=first;
  2568.   for (;o;o=o->next)
  2569.   {
  2570.     o->picture_space(x1,y1,x2,y2);    
  2571.     if (x<x2 && x>=x1 && y<y2 && y>=y1)
  2572.       return o;
  2573.   }
  2574.   return NULL; 
  2575. }
  2576.  
  2577. long last_tile_hit_x,last_tile_hit_y;
  2578.  
  2579. #define remapx(x) (x==0 ? -1 : x==tl-1 ? tl+1 : x)
  2580. #define remapy(y) (y==0 ? -1 : y==th-1 ? th+1 : y)
  2581.  
  2582. void level::foreground_intersect(long x1, long y1, long &x2, long &y2)
  2583. {
  2584. /*  if (x1==x2)
  2585.   { vforeground_intersect(x1,y1,y2);
  2586.     return ;
  2587.   }  */
  2588.  
  2589.   long tl=the_game->ftile_width(),th=the_game->ftile_height(),
  2590.     j,
  2591.     xp1,yp1,xp2,yp2,    // starting and ending points of block line segment 
  2592.     swap;               // temp var
  2593.   long blockx1,blocky1,blockx2,blocky2,block,bx,by;
  2594.   point_list *block_list;
  2595.   unsigned char *bdat;
  2596.  
  2597.   blockx1=x1;
  2598.   blocky1=y1;
  2599.   blockx2=x2;
  2600.   blocky2=y2;
  2601.   if (blockx1>blockx2) { swap=blockx1; blockx1=blockx2; blockx2=swap; }
  2602.   if (blocky1>blocky2) { swap=blocky1; blocky1=blocky2; blocky2=swap; }
  2603.   blockx1=(blockx1-2)/tl-1;
  2604.   blockx2=(blockx2+tl+2)/tl+1;
  2605.   blocky1=(blocky1-2)/th-1;
  2606.   blocky2=(blocky2+th+2)/th+1;
  2607.  
  2608.  
  2609.   if (blockx2>=foreground_width()) { x2=tl*foreground_width()-1; }
  2610.   if (blocky2>=foreground_height()) { y2=th*foreground_height()-1; }  
  2611.   blockx1=max(blockx1,0);
  2612.   blocky1=max(blocky1,0);  
  2613.  
  2614.   if ((blockx1>blockx2) || (blocky1>blocky2)) return ;
  2615.  
  2616.   // now check all the map positions this line could intersect
  2617.   for (bx=blockx1;bx<=blockx2;bx++)
  2618.   {
  2619.     for (by=blocky1;by<=blocky2;by++)
  2620.     {
  2621.       block=the_game->get_map_fg(bx,by);
  2622.       if (block>BLACK)        // don't check BLACK, should be no points in it
  2623.       {
  2624.         // now check the all the line segments in the block
  2625.         foretile *f=the_game->get_fg(block);
  2626.         block_list=f->points;
  2627.         unsigned char total=block_list->tot;
  2628.         bdat=block_list->data;
  2629.         unsigned char *ins=f->points->inside;
  2630.     long xo=bx*tl,yo=by*th;
  2631.         for (j=0;j<total-1;j++,ins++)
  2632.         {
  2633.           // find the starting and ending points for this segment
  2634.       xp1=xo+remapx(*bdat);
  2635.       bdat++;
  2636.  
  2637.       yp1=yo+remapy(*bdat);
  2638.       bdat++;
  2639.  
  2640.       xp2=xo+remapx(*bdat);
  2641.       yp2=yo+remapy(bdat[1]);
  2642.  
  2643.  
  2644.       long ox2=x2,oy2=y2;
  2645.           if (*ins)      
  2646.             setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,1); 
  2647.           else
  2648.             setback_intersect(x1,y1,x2,y2,xp1,yp1,xp2,yp2,-1); 
  2649.       if (ox2!=x2 || oy2!=y2)
  2650.       {
  2651.         last_tile_hit_x=bx;
  2652.         last_tile_hit_y=by;
  2653.       }
  2654.  
  2655.         }       
  2656.       }
  2657.     }
  2658.   }  
  2659. }
  2660.  
  2661.  
  2662. void level::vforeground_intersect(long x1, long y1, long &y2)
  2663. {
  2664.   long tl=f_wid,th=f_hi,
  2665.     j,
  2666.     xp1,yp1,xp2,yp2,    // starting and ending points of block line segment 
  2667.     swap;               // temp var
  2668.   long blocky1,blocky2,block,bx,by,checky1,checkx,checky2;
  2669.   point_list *block_list;
  2670.   unsigned char *bdat;
  2671.  
  2672.   int y_addback;
  2673.   if (y1>y2)
  2674.   {
  2675.     blocky1=y2/th;
  2676.     blocky2=y1/th;    
  2677.     y_addback=blocky2*f_hi;
  2678.   } else
  2679.   {
  2680.     blocky1=y1/th;
  2681.     blocky2=y2/th;
  2682.     y_addback=blocky1*f_hi;
  2683.   }
  2684.  
  2685.   y1-=y_addback;
  2686.   y2-=y_addback;
  2687.  
  2688.   bx=x1/f_wid;
  2689.   checkx=x1-bx*f_wid;
  2690.  
  2691.  
  2692.   // now check all the map positions this line could intersect
  2693.  
  2694.   for (by=blocky1;by<=blocky2;by++,y1-=f_hi,y2-=f_hi,y_addback+=f_hi)
  2695.   {
  2696.     block=the_game->get_map_fg(bx,by);
  2697.  
  2698.     // now check the all the line segments in the block
  2699.     foretile *f=the_game->get_fg(block);
  2700.     block_list=f->points;
  2701.  
  2702.     unsigned char total=block_list->tot;
  2703.     bdat=block_list->data;
  2704.     unsigned char *ins=f->points->inside;
  2705.  
  2706. //    long xo=bx*tl,yo=by*th;
  2707.     for (j=0;j<total-1;j++,ins++)
  2708.     {
  2709.       // find the starting and ending points for this segment
  2710.       xp1=remapx(*bdat);
  2711.       bdat++;
  2712.  
  2713.       yp1=remapy(*bdat);
  2714.       bdat++;
  2715.  
  2716.       xp2=remapx(*bdat);
  2717.       yp2=remapy(bdat[1]);
  2718.  
  2719.  
  2720.       long oy2=y2;
  2721.       if (*ins)      
  2722.         setback_intersect(checkx,y1,checkx,y2,xp1,yp1,xp2,yp2,1); 
  2723.       else
  2724.         setback_intersect(checkx,y1,checkx,y2,xp1,yp1,xp2,yp2,-1); 
  2725.       if (oy2!=y2)
  2726.       {
  2727.     last_tile_hit_x=bx;
  2728.     last_tile_hit_y=by;
  2729.       }
  2730.     }
  2731.   }
  2732.   y2+=y_addback;
  2733. }
  2734.  
  2735.  
  2736.  
  2737. void level::send_signal(long signal)
  2738. {
  2739.   if (signal)   // signal 0 is never sent!
  2740.   {
  2741.     game_object *o=first_active;
  2742.     for (;o;o=o->next_active)
  2743.       o->recieve_signal(signal);  
  2744.   }
  2745. }
  2746.  
  2747.  
  2748. int level::crush(game_object *by_who, int xamount, int yamount)
  2749. {
  2750.   long xv,yv,crushed=0;  
  2751.   game_object *o=first_active;
  2752.   for (;o;o=o->next_active)
  2753.   {
  2754.     if (o->hurtable() && o!=by_who)
  2755.     {      
  2756.       xv=-xamount;
  2757.       yv=-yamount;    
  2758.       if (o->try_move(o->x,o->y,xv,yv,3)==by_who)
  2759.       {      
  2760.     xv=xamount;
  2761.     yv=yamount;
  2762.     o->try_move(o->x,o->y,xv,yv,3);
  2763.     if (xv==0 && yv==0)
  2764.     {
  2765.       if (o->state!=dead && o->state!=dieing)
  2766.         o->do_damage(by_who->current_figure()->hit_damage,by_who,o->x,o->y,0,0);
  2767.  
  2768. /*      {          
  2769.         if (o->has_sequence(dieing))
  2770.           o->set_state(dieing);
  2771.         else o->set_state(dead);
  2772.           o->hp=0;        
  2773.       }        */
  2774.       crushed=1;      
  2775.     }
  2776.       }    
  2777.     }    
  2778.   }
  2779.  
  2780.   return crushed;  
  2781. }
  2782.  
  2783.  
  2784. int level::platform_push(game_object *by_who, int xamount, int yamount)
  2785. {
  2786.   int failed=0;
  2787.   long xv,yv;
  2788.   game_object *o=first_active;
  2789.   for (;o;o=o->next_active)  
  2790.   {
  2791.     if (o->is_playable() && o->state!=dieing && o->state!=dead)  
  2792.     {      
  2793.       // check to see if the platform is going up and will run into us.      
  2794.       long tvx,tvy;
  2795.       if (yamount<0)
  2796.       {
  2797.     tvx=-xamount;
  2798.     tvy=-yamount;
  2799.     if (o->try_move(o->x,o->y,tvx,tvy,1)==by_who)
  2800.     {
  2801.       o->x+=tvx;
  2802.       o->y+=tvy;       
  2803.     }
  2804.       }
  2805.  
  2806. /*      xv=xamount;    
  2807.       yv=yamount;
  2808.       tvx,tvy;
  2809.       if (xv>0) tvx=xv+1; else if (xv<0) tvx=xv-1; else tvx=0;
  2810.       if (yv>0) tvy=yv+1; else if (yv<0) tvx=yv-1; else tvy=0;
  2811.       if (o->try_move(o->x,o->y,tvx,tvy,1)==by_who)  // we the platform hit us?
  2812.       {
  2813.     o->x+=tvx;
  2814.     o->y+=tvy;       
  2815.       }*/
  2816.  
  2817.       xv=0;   
  2818.       yv=2;
  2819.       if (o->try_move(o->x,o->y,xv,yv,1)==by_who)  // are we standing on the platform?
  2820.       {      
  2821.     by_who->x=-by_who->x;
  2822.     xv=xamount;
  2823.     yv=yamount;
  2824.     o->try_move(o->x,o->y,xv,yv,3); 
  2825.     if (xv!=xamount || yv!=yamount) failed=1;
  2826.     o->x+=xv;
  2827.     o->y+=yv;
  2828.     by_who->x=-by_who->x;
  2829.       }    
  2830.     }    
  2831.   }
  2832.   return !failed;
  2833. }
  2834.  
  2835. int level::push_characters(game_object *by_who, int xamount, int yamount)
  2836. {
  2837.   long xv,yv;
  2838.   int failed=0;
  2839.   game_object *o=first_active;
  2840.   for (;o;o=o->next_active)  
  2841.   {
  2842.     if ((o->is_playable() || o->pushable()) && o->state!=dieing && o->state!=dead)  
  2843.     {      
  2844.       xv=-xamount;    
  2845.       yv=-yamount;
  2846.       long tvx,tvy;
  2847.       if (xv>0) tvx=xv+1; else if (xv<0) tvx=xv-1; else tvx=0;
  2848.       if (yv>0) tvy=yv+1; else if (yv<0) tvx=yv-1; else tvy=0;
  2849.       if (o->try_move(o->x+xamount,o->y+yamount,tvx,tvy,3)==by_who)
  2850.       {      
  2851.     xv=(xamount-tvx);
  2852.     yv=(yamount-tvy);
  2853.     o->try_move(o->x,o->y,xv,yv,3);       
  2854.     o->x+=xv;
  2855.     o->y+=yv;
  2856.     if (xv!=xamount-tvx || yv!=yamount-tvy)
  2857.       failed=1;
  2858.       }    
  2859.     }    
  2860.   }
  2861.   return !failed;
  2862. }
  2863.  
  2864. game_object *level::find_xrange(int x, int y, int type, int xd)
  2865. {
  2866.   long find_ydist=100000;
  2867.   game_object *find=NULL;
  2868.   game_object *o=first_active;
  2869.   for (;o;o=o->next_active)  
  2870.   {
  2871.     if (o->otype==type)
  2872.     {
  2873.       int x_dist=abs(x-o->x);
  2874.       int y_dist=abs(y-o->y);
  2875.  
  2876.       if (x_dist<xd  && y_dist<find_ydist)
  2877.       {   
  2878.     find_ydist=y_dist;
  2879.     find=o;
  2880.       }
  2881.     }
  2882.   }
  2883.   return find;
  2884. }
  2885.  
  2886.  
  2887. game_object *level::find_xclosest(int x, int y, int type, game_object *who)
  2888. {
  2889.   long find_ydist=100000,find_xdist=0xffffff;
  2890.   game_object *find=NULL;
  2891.   game_object *o=first_active;
  2892.   for (;o;o=o->next_active)  
  2893.   {
  2894.     if (o->otype==type && o!=who)
  2895.     {
  2896.       int x_dist=abs(x-o->x);
  2897.       if (x_dist<find_xdist)
  2898.       {
  2899.     find_xdist=x_dist;
  2900.     find_ydist=abs(y-o->y);
  2901.     find=o;
  2902.       }
  2903.       else if (x_dist==find_xdist)
  2904.       {
  2905.     int y_dist=abs(y-o->y);
  2906.     if (y_dist<find_ydist)
  2907.     {
  2908.       find_ydist=y_dist;
  2909.       find=o;
  2910.     }
  2911.       }
  2912.     }
  2913.   }
  2914.   return find;
  2915. }
  2916.  
  2917. game_object *level::find_closest(int x, int y, int type, game_object *who)
  2918. {
  2919.   long find_dist=100000;
  2920.   game_object *find=NULL;
  2921.   game_object *o=first_active;
  2922.   for (;o;o=o->next_active)  
  2923.   {
  2924.     if (o->otype==type && o!=who)
  2925.     {
  2926.       int d=(x-o->x)*(x-o->x)+(y-o->y)*(y-o->y);
  2927.       if (d<find_dist)
  2928.       {
  2929.     find=o;
  2930.     find_dist=d;
  2931.       }
  2932.     }
  2933.   }
  2934.   return find;
  2935. }
  2936.  
  2937.  
  2938.  
  2939. void level::remove_light(light_source *which)
  2940. {
  2941.   if (which->known)
  2942.   {
  2943.     game_object *o=first;
  2944.     for (;o;o=o->next)
  2945.     {
  2946.       int t=o->total_lights();
  2947.       int i=0;
  2948.       for (;i<t;i++)
  2949.         if (o->get_light(i)==which)
  2950.       o->remove_light(o->get_light(i));
  2951.     }
  2952.   }
  2953.   delete_light(which);
  2954. }
  2955.  
  2956.  
  2957. game_object *level::find_type(int type, int skip)
  2958. {
  2959.   game_object *l=NULL;
  2960.   game_object *o=first;
  2961.   for (;o;o=o->next)
  2962.   {
  2963.     if (o->otype==type)
  2964.     {
  2965.       if (!skip)
  2966.         return o;      
  2967.       skip--;
  2968.       l=o;
  2969.     }
  2970.   }
  2971.   return l;
  2972. }
  2973.  
  2974. void level::hurt_radius(long x, long y,long r, long m, game_object *from, game_object *exclude, 
  2975.             int max_push)
  2976. {
  2977.   if (r<1) return ;   // avoid dev vy zero
  2978.   game_object *o=first_active;
  2979.   for (;o;o=o->next_active)
  2980.   {
  2981.     if (o!=exclude && o->hurtable())
  2982.     {
  2983.       long y1=o->y,y2=o->y-o->picture()->height();
  2984.       long cx=abs(o->x-x),cy1=abs(y1-y),d1,d2,cy2=abs(y2-y);
  2985.       if (cx<cy1)
  2986.         d1=cx+cy1-(cx>>1);
  2987.       else d1=cx+cy1-(cy1>>1);
  2988.  
  2989.       if (cx<cy2)
  2990.         d2=cx+cy2-(cx>>1);
  2991.       else d2=cx+cy2-(cy2>>1);
  2992.       if (d2<d1)
  2993.         d1=d2;
  2994.  
  2995.  
  2996.  
  2997.       if (d1<r)
  2998.       {
  2999.  
  3000.     int px=(r-cx)*max_push/r,py=(r-cy1)*max_push/r;
  3001.     if (o->x<x)
  3002.           px=-px;
  3003.     if (o->y<y)
  3004.           py=-py;
  3005.     o->do_damage((r-d1)*m/r,from,x,y1,px,py);
  3006.       }
  3007.  
  3008.  
  3009.     }
  3010.   }
  3011.  
  3012. }
  3013.  
  3014.  
  3015.  
  3016. game_object *level::get_random_start(int min_player_dist, view *exclude)
  3017. {
  3018.   int t=0;
  3019.   game_object *o=first;
  3020.   for (;o;o=o->next)
  3021.     if (o->otype==start_position_type) t++;    // count how many starts there are in the level
  3022.  
  3023.   if (t==0) return NULL;                       // there aren't any starts in level!
  3024.  
  3025.   int retries=t;
  3026.   do
  3027.   {
  3028.     int ctry=jrandom(t)+1;
  3029.     game_object *n=first;
  3030.     for (n=first;ctry && n;n=n->next)
  3031.     {
  3032.       if (n->otype==start_position_type) 
  3033.       {
  3034.     o=n;
  3035.         ctry--;
  3036.       }
  3037.     }
  3038.  
  3039.     int too_close=0;
  3040.     view *v=player_list;
  3041.     for (;v;v=v->next)
  3042.     { 
  3043.       if (v!=exclude)
  3044.       {
  3045.     long cx=abs(v->x_center()-o->x),cy=abs(v->y_center()-o->y),d;
  3046.     if (cx<cy)
  3047.           d=cx+cy-(cx>>1);
  3048.     else d=cx+cy-(cy>>1);
  3049.     if (d<min_player_dist) too_close=1;
  3050.       }
  3051.     }
  3052.     if (too_close) retries--;
  3053.     else retries=0;
  3054.   } while (retries);
  3055.  
  3056.   return o;
  3057. }
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063. void level::insert_players()
  3064. {
  3065.  
  3066.   int start=0;
  3067.   int i=0;
  3068.   for (;i<total_objects;i++)
  3069.     if (!strcmp(object_names[i],"START"))
  3070.       start=i;
  3071.  
  3072.   view *f=player_list;
  3073.   for (;f;f=f->next)  
  3074.   {
  3075.     long x=50,y=50;
  3076.     game_object *st=find_type(start,f->player_number);    
  3077.     if (st)
  3078.     {
  3079.       f->focus->x=st->x;
  3080.       f->focus->y=st->y;
  3081.     }
  3082.     add_object_after(f->focus,st);
  3083.   }
  3084.  
  3085. }
  3086.  
  3087.  
  3088. void level::add_attacker(game_object *who)
  3089. {
  3090.   if (attack_total>=attack_list_size)  // see if we need to grow the list size..
  3091.   {
  3092.     attack_list_size++;
  3093.     attack_list=(game_object **)jrealloc(attack_list,sizeof(game_object *)*attack_list_size,
  3094.                               "attack_list");    
  3095.   }
  3096.   attack_list[attack_total]=who;
  3097.   attack_total++;
  3098. }
  3099.  
  3100.  
  3101.  
  3102. void level::add_target(game_object *who)
  3103. {
  3104.   if (target_total>=target_list_size)  // see if we need to grow the list size..
  3105.   {
  3106.     target_list_size++;
  3107.     target_list=(game_object **)jrealloc(target_list,sizeof(game_object *)*target_list_size,
  3108.                               "target_list");    
  3109.   }
  3110.   target_list[target_total]=who;
  3111.   target_total++;
  3112. }
  3113.  
  3114.  
  3115.  
  3116. void level::add_block(game_object *who)
  3117. {
  3118.   if (block_total>=block_list_size)  // see if we need to grow the list size..
  3119.   {
  3120.     block_list_size++;
  3121.     block_list=(game_object **)jrealloc(block_list,sizeof(game_object *)*block_list_size,
  3122.                               "block_list");    
  3123.   }
  3124.   block_list[block_total]=who;
  3125.   block_total++;
  3126. }
  3127.  
  3128.  
  3129. void level::add_all_block(game_object *who)
  3130. {
  3131.   if (all_block_total>=all_block_list_size)  // see if we need to grow the list size..
  3132.   {
  3133.     all_block_list_size++;
  3134.     all_block_list=(game_object **)jrealloc(all_block_list,sizeof(game_object *)*all_block_list_size,
  3135.                               "all_block_list");    
  3136.   }
  3137.   all_block_list[all_block_total]=who;
  3138.   all_block_total++;
  3139. }
  3140.  
  3141.  
  3142. game_object *level::find_object_in_area(long x, long y, long x1, long y1, long x2, long y2,
  3143.                      Cell *list, game_object *exclude)
  3144. {
  3145.   game_object *closest=NULL;
  3146.   long closest_distance=0xfffffff,distance,xo,yo;
  3147.   game_object *o=first_active;
  3148.   for (;o;o=o->next_active)
  3149.   {
  3150.     long xp1,yp1,xp2,yp2;
  3151.     o->picture_space(xp1,yp1,xp2,yp2);
  3152.  
  3153.  
  3154.     if (!(xp1>x2 || xp2<x1 || yp1>y2 || yp2<y1) && o!=exclude)
  3155.     {
  3156.       // check to see if the type is in the list
  3157.       Cell *v=list;
  3158.       for (;!NILP(v) && lnumber_value(CAR(v))!=o->otype;v=CDR(v));
  3159.       if (!NILP(v))
  3160.       {
  3161.     xo=abs(o->x-x);
  3162.     yo=abs(o->y-y);
  3163.     distance=xo*xo+yo*yo;
  3164.     if (distance<closest_distance)
  3165.     {
  3166.       closest_distance=distance;
  3167.       closest=o;
  3168.     }
  3169.       }
  3170.     }
  3171.   }
  3172.   return closest;
  3173. }
  3174.  
  3175.  
  3176.  
  3177.  
  3178. game_object *level::find_object_in_angle(long x, long y, long start_angle, long end_angle,
  3179.                     void *list, game_object *exclude)
  3180. {
  3181.   game_object *closest=NULL;
  3182.   long closest_distance=0xfffffff,distance,xo,yo;
  3183.   game_object *o=first_active;
  3184.   for (;o;o=o->next_active)
  3185.   {
  3186.     long angle=lisp_atan2(o->y-y,o->x-x);
  3187.     if (((start_angle<=end_angle && (angle>=start_angle && angle<=end_angle))
  3188.     || (start_angle>end_angle && (angle>=start_angle || angle<=end_angle)))
  3189.     && o!=exclude)
  3190.     {
  3191.       // check to see if the type is in the list
  3192.       Cell *v=(Cell *)list;
  3193.       for (;!NILP(v) && lnumber_value(CAR(v))!=o->otype;v=CDR(v));
  3194.       if (!NILP(v))
  3195.       {
  3196.     xo=abs(o->x-x);
  3197.     yo=abs(o->y-y);
  3198.     distance=xo*xo+yo*yo;
  3199.     if (distance<closest_distance)
  3200.     {
  3201.       closest_distance=distance;
  3202.       closest=o;
  3203.     }
  3204.       }
  3205.     }
  3206.   }
  3207.   return closest;
  3208. }
  3209.  
  3210.  
  3211. object_node *level::make_not_list(object_node *list)
  3212. {
  3213.   object_node *f=NULL,*l;
  3214.   game_object *o=first;
  3215.   for (;o;o=o->next)
  3216.   {
  3217.     if (!object_to_number_in_list(o,list))
  3218.     {
  3219.       object_node *q=new object_node(o,NULL);
  3220.       if (f)
  3221.         l->next=q;
  3222.       else f=q;
  3223.       l=q;
  3224.     }
  3225.   }
  3226.   return f;
  3227. }
  3228.  
  3229. FILE *open_FILE(char *filename, char *mode);
  3230.  
  3231. void level::write_object_info(char *filename)
  3232. {
  3233.   FILE *fp=open_FILE(filename,"wb");
  3234.   if (fp)
  3235.   {
  3236.     int i=0;
  3237.     game_object *o=first;
  3238.     for (;o;o=o->next)
  3239.     {
  3240.       fprintf(fp,"%3d %s %4d %4d %4d %4d %04d\n",i++,object_names[o->otype],o->x,o->y,
  3241.           o->xvel(),o->yvel(),o->current_frame);
  3242.     }
  3243.     fclose(fp);
  3244.   }
  3245. }
  3246.  
  3247.  
  3248. area_controller::area_controller(long X, long Y, long W, long H, area_controller *Next)
  3249.   x=X; y=Y; w=W; h=H; 
  3250.   next=Next; active=0; 
  3251.  
  3252.   ambient=-1;
  3253.   view_xoff=-1;
  3254.   view_yoff=-1;
  3255.   ambient_speed=2; 
  3256.   view_xoff_speed=4;
  3257.   view_yoff_speed=4;
  3258. }
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.